From 2c032d8f1c6292c1338a615e6ec40252889ba85c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 22 Jan 2015 00:29:39 +0100 Subject: Imported Upstream version 1.0.0 --- src/Makefile.am | 308 +- src/Makefile.in | 1265 ++-- src/NetworkManagerUtils.c | 1580 ++++- src/NetworkManagerUtils.h | 136 +- src/config/nm-config-device.c | 82 - src/config/nm-config-device.h | 47 - src/config/nm-config.c | 604 -- src/config/nm-config.h | 78 - src/config/tests/Makefile.am | 30 - src/config/tests/Makefile.in | 864 --- src/config/tests/NetworkManager.conf | 15 - src/config/tests/bad.conf | 1 - src/config/tests/conf.d/00-overrides.conf | 11 - src/config/tests/conf.d/10-more.conf | 11 - src/config/tests/conf.d/90-last.conf | 5 - src/config/tests/nm-test-device.c | 101 - src/config/tests/nm-test-device.h | 52 - src/config/tests/test-config.c | 305 - src/devices/adsl/Makefile.am | 11 +- src/devices/adsl/Makefile.in | 17 +- src/devices/adsl/exports.ver | 1 - src/devices/adsl/nm-atm-manager.c | 34 +- src/devices/adsl/nm-atm-manager.h | 6 +- src/devices/adsl/nm-device-adsl.c | 129 +- src/devices/adsl/nm-device-adsl.h | 4 +- src/devices/bluetooth/Makefile.am | 26 +- src/devices/bluetooth/Makefile.in | 92 +- src/devices/bluetooth/exports.ver | 1 - src/devices/bluetooth/nm-bluez-common.h | 4 +- src/devices/bluetooth/nm-bluez-device.c | 285 +- src/devices/bluetooth/nm-bluez-device.h | 11 +- src/devices/bluetooth/nm-bluez-manager.c | 35 +- src/devices/bluetooth/nm-bluez-manager.h | 6 +- src/devices/bluetooth/nm-bluez4-adapter.c | 20 +- src/devices/bluetooth/nm-bluez4-adapter.h | 6 +- src/devices/bluetooth/nm-bluez4-manager.c | 2 + src/devices/bluetooth/nm-bluez4-manager.h | 6 +- src/devices/bluetooth/nm-bluez5-dun.c | 410 ++ src/devices/bluetooth/nm-bluez5-dun.h | 46 + src/devices/bluetooth/nm-bluez5-manager.c | 4 +- src/devices/bluetooth/nm-bluez5-manager.h | 6 +- src/devices/bluetooth/nm-bt-enum-types.c | 3 +- src/devices/bluetooth/nm-bt-error.c | 35 + src/devices/bluetooth/nm-bt-error.h | 35 + src/devices/bluetooth/nm-device-bt.c | 262 +- src/devices/bluetooth/nm-device-bt.h | 12 +- src/devices/nm-device-bond.c | 227 +- src/devices/nm-device-bond.h | 24 +- src/devices/nm-device-bridge.c | 288 +- src/devices/nm-device-bridge.h | 26 +- src/devices/nm-device-ethernet-utils.c | 55 + src/devices/nm-device-ethernet-utils.h | 26 + src/devices/nm-device-ethernet.c | 523 +- src/devices/nm-device-ethernet.h | 25 +- src/devices/nm-device-factory.c | 52 + src/devices/nm-device-factory.h | 125 +- src/devices/nm-device-generic.c | 24 +- src/devices/nm-device-generic.h | 11 +- src/devices/nm-device-gre.c | 117 +- src/devices/nm-device-gre.h | 16 +- src/devices/nm-device-infiniband.c | 231 +- src/devices/nm-device-infiniband.h | 25 +- src/devices/nm-device-logging.h | 46 + src/devices/nm-device-macvlan.c | 64 +- src/devices/nm-device-macvlan.h | 16 +- src/devices/nm-device-private.h | 23 +- src/devices/nm-device-team.c | 894 --- src/devices/nm-device-team.h | 64 - src/devices/nm-device-tun.c | 109 +- src/devices/nm-device-tun.h | 16 +- src/devices/nm-device-veth.c | 49 +- src/devices/nm-device-veth.h | 16 +- src/devices/nm-device-vlan.c | 333 +- src/devices/nm-device-vlan.h | 22 +- src/devices/nm-device-vxlan.c | 155 +- src/devices/nm-device-vxlan.h | 16 +- src/devices/nm-device.c | 4414 +++++++----- src/devices/nm-device.h | 92 +- src/devices/team/Makefile.am | 68 + src/devices/team/Makefile.in | 845 +++ src/devices/team/exports.ver | 6 + src/devices/team/nm-device-team-glue.h | 73 + src/devices/team/nm-device-team.c | 777 +++ src/devices/team/nm-device-team.h | 56 + src/devices/team/nm-team-enum-types.c | 12 + src/devices/team/nm-team-enum-types.h | 17 + src/devices/team/nm-team-factory.c | 93 + src/devices/team/nm-team-factory.h | 37 + src/devices/wifi/Makefile.am | 12 +- src/devices/wifi/Makefile.in | 18 +- src/devices/wifi/exports.ver | 1 - src/devices/wifi/nm-device-olpc-mesh.c | 127 +- src/devices/wifi/nm-device-olpc-mesh.h | 12 +- src/devices/wifi/nm-device-wifi.c | 931 ++- src/devices/wifi/nm-device-wifi.h | 16 +- src/devices/wifi/nm-wifi-ap-utils.c | 316 +- src/devices/wifi/nm-wifi-ap-utils.h | 9 +- src/devices/wifi/nm-wifi-ap.c | 211 +- src/devices/wifi/nm-wifi-ap.h | 76 +- src/devices/wifi/nm-wifi-enum-types.c | 44 - src/devices/wifi/nm-wifi-enum-types.h | 4 - src/devices/wifi/nm-wifi-factory.c | 18 +- src/devices/wifi/tests/Makefile.am | 9 +- src/devices/wifi/tests/Makefile.in | 15 +- src/devices/wifi/tests/test-wifi-ap-utils.c | 231 +- src/devices/wimax/Makefile.am | 12 +- src/devices/wimax/Makefile.in | 18 +- src/devices/wimax/exports.ver | 1 - src/devices/wimax/iwmxsdk.c | 10 +- src/devices/wimax/iwmxsdk.h | 9 +- src/devices/wimax/nm-device-wimax.c | 132 +- src/devices/wimax/nm-device-wimax.h | 13 +- src/devices/wimax/nm-wimax-factory.c | 18 +- src/devices/wimax/nm-wimax-nsp.c | 33 +- src/devices/wimax/nm-wimax-nsp.h | 4 +- src/devices/wimax/nm-wimax-types.h | 4 +- src/devices/wimax/nm-wimax-util.c | 3 +- src/devices/wimax/nm-wimax-util.h | 9 +- src/devices/wwan/Makefile.am | 19 +- src/devices/wwan/Makefile.in | 46 +- src/devices/wwan/README | 45 - src/devices/wwan/exports.ver | 1 - src/devices/wwan/nm-device-modem.c | 207 +- src/devices/wwan/nm-device-modem.h | 6 +- src/devices/wwan/nm-modem-broadband.c | 283 +- src/devices/wwan/nm-modem-broadband.h | 7 +- src/devices/wwan/nm-modem-enum-types.c | 34 +- src/devices/wwan/nm-modem-enum-types.h | 6 +- src/devices/wwan/nm-modem-manager.c | 460 +- src/devices/wwan/nm-modem-manager.h | 6 +- src/devices/wwan/nm-modem-old-types.h | 70 - src/devices/wwan/nm-modem-old.c | 1139 --- src/devices/wwan/nm-modem-old.h | 53 - src/devices/wwan/nm-modem.c | 482 +- src/devices/wwan/nm-modem.h | 74 +- src/devices/wwan/nm-wwan-factory.c | 28 +- src/devices/wwan/nm-wwan-factory.h | 6 +- src/devices/wwan/wwan-exports.ver | 2 +- src/dhcp-manager/Makefile.am | 6 +- src/dhcp-manager/Makefile.in | 12 +- src/dhcp-manager/nm-dhcp-client.c | 1524 ++-- src/dhcp-manager/nm-dhcp-client.h | 162 +- src/dhcp-manager/nm-dhcp-dhclient-utils.c | 152 +- src/dhcp-manager/nm-dhcp-dhclient-utils.h | 15 +- src/dhcp-manager/nm-dhcp-dhclient.c | 228 +- src/dhcp-manager/nm-dhcp-dhclient.h | 26 +- src/dhcp-manager/nm-dhcp-dhcpcd.c | 131 +- src/dhcp-manager/nm-dhcp-dhcpcd.h | 22 +- src/dhcp-manager/nm-dhcp-helper.c | 327 +- src/dhcp-manager/nm-dhcp-listener.c | 290 + src/dhcp-manager/nm-dhcp-listener.h | 39 + src/dhcp-manager/nm-dhcp-manager.c | 607 +- src/dhcp-manager/nm-dhcp-manager.h | 68 +- src/dhcp-manager/nm-dhcp-systemd.c | 849 +++ src/dhcp-manager/nm-dhcp-systemd.h | 45 + src/dhcp-manager/nm-dhcp-utils.c | 732 ++ src/dhcp-manager/nm-dhcp-utils.h | 41 + src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c | 209 + src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h | 109 + .../src/libsystemd-network/dhcp-internal.h | 76 + .../src/libsystemd-network/dhcp-lease-internal.h | 87 + .../src/libsystemd-network/dhcp-network.c | 241 + .../src/libsystemd-network/dhcp-option.c | 257 + .../src/libsystemd-network/dhcp-packet.c | 204 + .../src/libsystemd-network/dhcp-protocol.h | 141 + .../src/libsystemd-network/dhcp6-internal.h | 81 + .../src/libsystemd-network/dhcp6-lease-internal.h | 64 + .../src/libsystemd-network/dhcp6-network.c | 198 + .../src/libsystemd-network/dhcp6-option.c | 323 + .../src/libsystemd-network/dhcp6-protocol.h | 141 + .../src/libsystemd-network/network-internal.c | 484 ++ .../src/libsystemd-network/network-internal.h | 78 + .../src/libsystemd-network/sd-dhcp-client.c | 1726 +++++ .../src/libsystemd-network/sd-dhcp-lease.c | 865 +++ .../src/libsystemd-network/sd-dhcp6-client.c | 1242 ++++ .../src/libsystemd-network/sd-dhcp6-lease.c | 223 + src/dhcp-manager/systemd-dhcp/src/shared/async.h | 27 + src/dhcp-manager/systemd-dhcp/src/shared/fileio.c | 817 +++ src/dhcp-manager/systemd-dhcp/src/shared/fileio.h | 45 + .../systemd-dhcp/src/shared/in-addr-util.c | 294 + .../systemd-dhcp/src/shared/in-addr-util.h | 49 + src/dhcp-manager/systemd-dhcp/src/shared/list.h | 138 + src/dhcp-manager/systemd-dhcp/src/shared/macro.h | 413 ++ src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h | 34 + .../systemd-dhcp/src/shared/siphash24.c | 137 + .../systemd-dhcp/src/shared/siphash24.h | 6 + .../systemd-dhcp/src/shared/socket-util.h | 118 + .../systemd-dhcp/src/shared/sparse-endian.h | 88 + src/dhcp-manager/systemd-dhcp/src/shared/strv.c | 616 ++ src/dhcp-manager/systemd-dhcp/src/shared/strv.h | 137 + .../systemd-dhcp/src/shared/time-util.c | 1003 +++ .../systemd-dhcp/src/shared/time-util.h | 111 + .../systemd-dhcp/src/shared/unaligned.h | 66 + src/dhcp-manager/systemd-dhcp/src/shared/utf8.c | 314 + src/dhcp-manager/systemd-dhcp/src/shared/utf8.h | 42 + src/dhcp-manager/systemd-dhcp/src/shared/util.c | 7350 ++++++++++++++++++++ src/dhcp-manager/systemd-dhcp/src/shared/util.h | 1038 +++ .../systemd-dhcp/src/systemd/_sd-common.h | 78 + .../systemd-dhcp/src/systemd/sd-dhcp-client.h | 75 + .../systemd-dhcp/src/systemd/sd-dhcp-lease.h | 54 + .../systemd-dhcp/src/systemd/sd-dhcp6-client.h | 66 + .../systemd-dhcp/src/systemd/sd-dhcp6-lease.h | 42 + .../systemd-dhcp/src/systemd/sd-event.h | 135 + .../systemd-dhcp/src/systemd/sd-id128.h | 113 + src/dhcp-manager/tests/Makefile.am | 28 +- src/dhcp-manager/tests/Makefile.in | 77 +- src/dhcp-manager/tests/test-dhcp-dhclient.c | 158 +- src/dhcp-manager/tests/test-dhcp-utils.c | 723 ++ src/dns-manager/nm-dns-dnsmasq.c | 33 +- src/dns-manager/nm-dns-dnsmasq.h | 6 +- src/dns-manager/nm-dns-manager.c | 74 +- src/dns-manager/nm-dns-manager.h | 17 +- src/dns-manager/nm-dns-plugin.c | 43 +- src/dns-manager/nm-dns-plugin.h | 6 +- src/dns-manager/nm-dns-unbound.c | 2 + src/dns-manager/nm-dns-unbound.h | 6 +- src/dns-manager/nm-dns-utils.c | 3 + src/dns-manager/nm-dns-utils.h | 4 +- src/dnsmasq-manager/nm-dnsmasq-manager.c | 95 +- src/dnsmasq-manager/nm-dnsmasq-manager.h | 11 +- src/dnsmasq-manager/nm-dnsmasq-utils.c | 3 +- src/dnsmasq-manager/nm-dnsmasq-utils.h | 6 +- src/dnsmasq-manager/tests/Makefile.am | 6 +- src/dnsmasq-manager/tests/Makefile.in | 12 +- src/dnsmasq-manager/tests/test-dnsmasq-utils.c | 2 + src/firewall-manager/nm-firewall-manager.c | 360 - src/firewall-manager/nm-firewall-manager.h | 73 - src/logging/nm-logging.c | 482 -- src/logging/nm-logging.h | 142 - src/main-utils.c | 279 + src/main-utils.h | 39 + src/main.c | 265 +- src/nm-activation-request.c | 9 +- src/nm-activation-request.h | 14 +- src/nm-active-connection.c | 345 +- src/nm-active-connection.h | 18 +- src/nm-auth-manager.c | 657 ++ src/nm-auth-manager.h | 78 + src/nm-auth-subject.c | 416 +- src/nm-auth-subject.h | 55 +- src/nm-auth-utils.c | 480 ++ src/nm-auth-utils.h | 97 + src/nm-config.c | 675 ++ src/nm-config.h | 80 + src/nm-connection-provider.c | 2 + src/nm-connection-provider.h | 10 +- src/nm-connectivity.c | 30 +- src/nm-connectivity.h | 13 +- src/nm-dbus-manager.c | 23 +- src/nm-dbus-manager.h | 6 +- src/nm-dcb.c | 56 +- src/nm-dcb.h | 30 +- src/nm-default-route-manager.c | 1365 ++++ src/nm-default-route-manager.h | 74 + src/nm-device-glue.h | 5 +- src/nm-device-team-glue.h | 73 - src/nm-device-vlan-glue.h | 2 +- src/nm-dhcp4-config.c | 41 +- src/nm-dhcp4-config.h | 32 +- src/nm-dhcp6-config.c | 41 +- src/nm-dhcp6-config.h | 32 +- src/nm-dispatcher.c | 21 +- src/nm-dispatcher.h | 10 +- src/nm-enum-types.c | 533 +- src/nm-enum-types.h | 55 +- src/nm-firewall-manager.c | 440 ++ src/nm-firewall-manager.h | 75 + src/nm-iface-helper.c | 538 ++ src/nm-ip4-config-glue.h | 2 +- src/nm-ip4-config.c | 440 +- src/nm-ip4-config.h | 30 +- src/nm-ip6-config-glue.h | 2 +- src/nm-ip6-config.c | 394 +- src/nm-ip6-config.h | 26 +- src/nm-logging.c | 487 ++ src/nm-logging.h | 159 + src/nm-manager-auth.c | 656 -- src/nm-manager-auth.h | 108 - src/nm-manager-glue.h | 2 +- src/nm-manager.c | 988 +-- src/nm-manager.h | 97 +- src/nm-policy.c | 634 +- src/nm-policy.h | 13 +- src/nm-posix-signals.c | 62 + src/nm-posix-signals.h | 36 + src/nm-ppp-manager-glue.h | 7 +- src/nm-properties-changed-signal.c | 2 + src/nm-rfkill-manager.c | 2 +- src/nm-rfkill-manager.h | 10 +- src/nm-session-monitor-ck.c | 46 +- src/nm-session-monitor-null.c | 1 + src/nm-session-monitor-systemd.c | 1 + src/nm-session-monitor.h | 9 +- src/nm-session-utils.c | 23 +- src/nm-session-utils.h | 15 +- src/nm-settings-connection-glue.h | 7 +- src/nm-sleep-monitor-systemd.c | 56 +- src/nm-sleep-monitor-upower.c | 1 + src/nm-sleep-monitor.h | 9 +- src/nm-types.h | 94 +- src/platform/Makefile.in | 6 +- src/platform/nm-fake-platform.c | 108 +- src/platform/nm-fake-platform.h | 6 +- src/platform/nm-linux-platform.c | 623 +- src/platform/nm-linux-platform.h | 6 +- src/platform/nm-platform.c | 293 +- src/platform/nm-platform.h | 201 +- src/platform/tests/Makefile.am | 9 +- src/platform/tests/Makefile.in | 16 +- src/platform/tests/dump.c | 6 +- src/platform/tests/monitor.c | 2 + src/platform/tests/platform.c | 28 +- src/platform/tests/test-address.c | 8 +- src/platform/tests/test-cleanup.c | 24 +- src/platform/tests/test-common.c | 2 + src/platform/tests/test-link.c | 13 +- src/platform/tests/test-route.c | 48 +- src/platform/wifi/wifi-utils-nl80211.c | 59 +- src/platform/wifi/wifi-utils-nl80211.h | 8 +- src/platform/wifi/wifi-utils-private.h | 12 +- src/platform/wifi/wifi-utils-wext.c | 19 +- src/platform/wifi/wifi-utils-wext.h | 6 +- src/platform/wifi/wifi-utils.c | 23 +- src/platform/wifi/wifi-utils.h | 16 +- src/posix-signals/nm-posix-signals.c | 62 - src/posix-signals/nm-posix-signals.h | 36 - src/ppp-manager/Makefile.am | 10 +- src/ppp-manager/Makefile.in | 20 +- src/ppp-manager/nm-ppp-manager.c | 293 +- src/ppp-manager/nm-ppp-manager.h | 17 +- src/ppp-manager/nm-ppp-status.h | 6 +- src/ppp-manager/nm-pppd-plugin.c | 264 +- src/ppp-manager/nm-pppd-plugin.h | 19 +- src/rdisc/Makefile.in | 6 +- src/rdisc/nm-fake-rdisc.c | 2 + src/rdisc/nm-fake-rdisc.h | 6 +- src/rdisc/nm-lndp-rdisc.c | 150 +- src/rdisc/nm-lndp-rdisc.h | 6 +- src/rdisc/nm-rdisc.c | 23 +- src/rdisc/nm-rdisc.h | 16 +- src/rdisc/tests/Makefile.am | 14 +- src/rdisc/tests/Makefile.in | 24 +- src/rdisc/tests/rdisc.c | 5 +- src/settings/nm-agent-manager.c | 120 +- src/settings/nm-agent-manager.h | 27 +- src/settings/nm-inotify-helper.c | 2 + src/settings/nm-secret-agent.c | 47 +- src/settings/nm-secret-agent.h | 26 +- src/settings/nm-settings-connection.c | 644 +- src/settings/nm-settings-connection.h | 59 +- src/settings/nm-settings-error.c | 33 - src/settings/nm-settings-error.h | 53 - src/settings/nm-settings-utils.c | 66 - src/settings/nm-settings-utils.h | 26 - src/settings/nm-settings.c | 272 +- src/settings/nm-settings.h | 9 +- src/settings/nm-system-config-interface.c | 45 +- src/settings/nm-system-config-interface.h | 6 +- src/settings/plugins/Makefile.am | 4 + src/settings/plugins/Makefile.in | 19 +- src/settings/plugins/example/Makefile.am | 15 +- src/settings/plugins/example/Makefile.in | 30 +- src/settings/plugins/example/common.h | 11 - src/settings/plugins/example/errors.c | 40 - .../plugins/example/nm-example-connection.c | 13 +- .../plugins/example/nm-example-connection.h | 6 +- src/settings/plugins/example/plugin.c | 13 +- src/settings/plugins/example/reader.c | 5 +- src/settings/plugins/example/writer.c | 3 +- src/settings/plugins/ibft/Makefile.am | 38 + src/settings/plugins/ibft/Makefile.in | 956 +++ src/settings/plugins/ibft/nm-ibft-connection.c | 66 + src/settings/plugins/ibft/nm-ibft-connection.h | 50 + src/settings/plugins/ibft/plugin.c | 210 + src/settings/plugins/ibft/plugin.h | 47 + src/settings/plugins/ibft/reader.c | 558 ++ src/settings/plugins/ibft/reader.h | 36 + src/settings/plugins/ibft/tests/Makefile.am | 49 + src/settings/plugins/ibft/tests/Makefile.in | 899 +++ .../plugins/ibft/tests/iscsiadm-test-bad-dns1 | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-dns2 | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-entry | 20 + .../plugins/ibft/tests/iscsiadm-test-bad-gateway | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-ipaddr | 21 + .../plugins/ibft/tests/iscsiadm-test-bad-record | 18 + src/settings/plugins/ibft/tests/iscsiadm-test-dhcp | 33 + .../plugins/ibft/tests/iscsiadm-test-static | 35 + src/settings/plugins/ibft/tests/iscsiadm-test-vlan | 19 + src/settings/plugins/ibft/tests/test-ibft.c | 292 + src/settings/plugins/ifcfg-rh/Makefile.am | 18 +- src/settings/plugins/ifcfg-rh/Makefile.in | 35 +- src/settings/plugins/ifcfg-rh/common.h | 4 - src/settings/plugins/ifcfg-rh/errors.c | 35 - .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 78 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 8 +- src/settings/plugins/ifcfg-rh/plugin.c | 30 +- src/settings/plugins/ifcfg-rh/reader.c | 1461 ++-- src/settings/plugins/ifcfg-rh/reader.h | 1 - src/settings/plugins/ifcfg-rh/shvar.c | 45 +- src/settings/plugins/ifcfg-rh/shvar.h | 2 + src/settings/plugins/ifcfg-rh/tests/Makefile.am | 27 +- src/settings/plugins/ifcfg-rh/tests/Makefile.in | 60 +- .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 | 21 - .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 | 21 - .../plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry | 35 - .../ifcfg-rh/tests/iscsiadm-test-bad-gateway | 21 - .../ifcfg-rh/tests/iscsiadm-test-bad-ipaddr | 21 - .../ifcfg-rh/tests/iscsiadm-test-bad-record | 18 - .../plugins/ifcfg-rh/tests/iscsiadm-test-dhcp | 33 - .../plugins/ifcfg-rh/tests/iscsiadm-test-static | 35 - .../ifcfg-rh/tests/network-scripts/Makefile.am | 10 +- .../ifcfg-rh/tests/network-scripts/Makefile.in | 16 +- .../ifcfg-rh/tests/network-scripts/ifcfg-test-ibft | 10 + .../tests/network-scripts/ifcfg-test-ibft-dhcp | 4 - .../tests/network-scripts/ifcfg-test-ibft-static | 4 - .../network-scripts/ifcfg-test-misc-variables | 3 + .../ifcfg-test-vlan-trailing-spaces | 11 + .../tests/network-scripts/ifcfg-test-wifi-band-a | 13 + .../ifcfg-test-wifi-band-a-channel-mismatch | 9 + .../ifcfg-test-wifi-band-bg-channel-mismatch | 9 + .../tests/network-scripts/ifcfg-test-wifi-open | 1 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c | 2 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 4159 +++++------ src/settings/plugins/ifcfg-rh/utils.c | 7 +- src/settings/plugins/ifcfg-rh/writer.c | 562 +- src/settings/plugins/ifcfg-suse/Makefile.am | 13 +- src/settings/plugins/ifcfg-suse/Makefile.in | 24 +- src/settings/plugins/ifcfg-suse/plugin.c | 16 +- src/settings/plugins/ifcfg-suse/plugin.h | 2 - src/settings/plugins/ifnet/Makefile.am | 27 +- src/settings/plugins/ifnet/Makefile.in | 46 +- src/settings/plugins/ifnet/connection_parser.c | 710 +- src/settings/plugins/ifnet/errors.c | 35 - src/settings/plugins/ifnet/errors.h | 30 - src/settings/plugins/ifnet/net_parser.c | 2 + src/settings/plugins/ifnet/net_utils.c | 229 +- src/settings/plugins/ifnet/net_utils.h | 22 +- src/settings/plugins/ifnet/nm-ifnet-connection.c | 5 +- src/settings/plugins/ifnet/nm-ifnet-connection.h | 4 +- src/settings/plugins/ifnet/plugin.c | 4 +- src/settings/plugins/ifnet/tests/Makefile.am | 18 +- src/settings/plugins/ifnet/tests/Makefile.in | 53 +- src/settings/plugins/ifnet/tests/test_all.c | 68 +- src/settings/plugins/ifnet/wpa_parser.c | 4 +- src/settings/plugins/ifupdown/Makefile.am | 21 +- src/settings/plugins/ifupdown/Makefile.in | 36 +- src/settings/plugins/ifupdown/interface_parser.c | 1 + .../plugins/ifupdown/nm-ifupdown-connection.c | 12 +- .../plugins/ifupdown/nm-ifupdown-connection.h | 6 +- src/settings/plugins/ifupdown/parser.c | 157 +- src/settings/plugins/ifupdown/plugin.c | 24 +- src/settings/plugins/ifupdown/plugin.h | 2 - src/settings/plugins/ifupdown/tests/Makefile.am | 19 +- src/settings/plugins/ifupdown/tests/Makefile.in | 39 +- .../plugins/ifupdown/tests/test-ifupdown.c | 215 +- src/settings/plugins/keyfile/Makefile.am | 17 +- src/settings/plugins/keyfile/Makefile.in | 35 +- src/settings/plugins/keyfile/common.h | 3 - src/settings/plugins/keyfile/errors.c | 35 - .../plugins/keyfile/nm-keyfile-connection.c | 14 +- .../plugins/keyfile/nm-keyfile-connection.h | 6 +- src/settings/plugins/keyfile/plugin.c | 18 +- src/settings/plugins/keyfile/plugin.h | 2 - src/settings/plugins/keyfile/reader.c | 619 +- src/settings/plugins/keyfile/tests/Makefile.am | 12 +- src/settings/plugins/keyfile/tests/Makefile.in | 39 +- .../keyfile/tests/keyfiles/ATT_Data_Connect_BT | 1 + .../keyfile/tests/keyfiles/ATT_Data_Connect_Plain | 1 + .../plugins/keyfile/tests/keyfiles/Makefile.am | 11 +- .../plugins/keyfile/tests/keyfiles/Makefile.in | 17 +- .../keyfile/tests/keyfiles/Test_Enum_Property | 8 + .../keyfile/tests/keyfiles/Test_Flags_Property | 11 + .../keyfile/tests/keyfiles/Test_Missing_ID_UUID | 9 + .../plugins/keyfile/tests/keyfiles/Test_minimal_1 | 2 + .../plugins/keyfile/tests/keyfiles/Test_minimal_2 | 1 + .../keyfile/tests/keyfiles/Test_minimal_slave_1 | 4 + .../keyfile/tests/keyfiles/Test_minimal_slave_2 | 7 + .../keyfile/tests/keyfiles/Test_minimal_slave_3 | 4 + .../keyfile/tests/keyfiles/Test_minimal_slave_4 | 4 + src/settings/plugins/keyfile/tests/test-keyfile.c | 1276 ++-- src/settings/plugins/keyfile/utils.c | 3 + src/settings/plugins/keyfile/utils.h | 1 + src/settings/plugins/keyfile/writer.c | 515 +- src/settings/tests/Makefile.am | 23 - src/settings/tests/Makefile.in | 854 --- src/settings/tests/test-wired-defname.c | 139 - src/supplicant-manager/nm-call-store.c | 10 +- src/supplicant-manager/nm-call-store.h | 6 +- src/supplicant-manager/nm-supplicant-config.c | 115 +- src/supplicant-manager/nm-supplicant-config.h | 4 +- src/supplicant-manager/nm-supplicant-interface.c | 20 +- src/supplicant-manager/nm-supplicant-interface.h | 5 +- src/supplicant-manager/nm-supplicant-manager.c | 14 +- src/supplicant-manager/nm-supplicant-manager.h | 6 +- .../nm-supplicant-settings-verify.c | 4 +- .../nm-supplicant-settings-verify.h | 6 +- src/supplicant-manager/nm-supplicant-types.h | 4 +- src/supplicant-manager/tests/Makefile.am | 6 +- src/supplicant-manager/tests/Makefile.in | 12 +- .../tests/test-supplicant-config.c | 77 +- src/tests/Makefile.am | 69 +- src/tests/Makefile.in | 304 +- src/tests/config/Makefile.am | 33 + src/tests/config/Makefile.in | 871 +++ src/tests/config/NetworkManager.conf | 15 + src/tests/config/bad.conf | 1 + src/tests/config/conf.d/00-overrides.conf | 11 + src/tests/config/conf.d/10-more.conf | 11 + src/tests/config/conf.d/90-last.conf | 5 + src/tests/config/nm-test-device.c | 99 + src/tests/config/nm-test-device.h | 50 + src/tests/config/test-config.c | 308 + src/tests/test-dcb.c | 2 + src/tests/test-dhcp-options.c | 937 --- src/tests/test-general-with-expect.c | 349 + src/tests/test-general.c | 357 +- src/tests/test-ip4-config.c | 49 +- src/tests/test-ip6-config.c | 87 +- src/tests/test-resolvconf-capture.c | 5 + src/tests/test-wired-defname.c | 130 + src/vpn-manager/nm-vpn-connection.c | 550 +- src/vpn-manager/nm-vpn-connection.h | 77 +- src/vpn-manager/nm-vpn-manager.c | 79 +- src/vpn-manager/nm-vpn-manager.h | 42 +- src/vpn-manager/nm-vpn-service.c | 92 +- src/vpn-manager/nm-vpn-service.h | 28 +- 526 files changed, 57669 insertions(+), 28708 deletions(-) delete mode 100644 src/config/nm-config-device.c delete mode 100644 src/config/nm-config-device.h delete mode 100644 src/config/nm-config.c delete mode 100644 src/config/nm-config.h delete mode 100644 src/config/tests/Makefile.am delete mode 100644 src/config/tests/Makefile.in delete mode 100644 src/config/tests/NetworkManager.conf delete mode 100644 src/config/tests/bad.conf delete mode 100644 src/config/tests/conf.d/00-overrides.conf delete mode 100644 src/config/tests/conf.d/10-more.conf delete mode 100644 src/config/tests/conf.d/90-last.conf delete mode 100644 src/config/tests/nm-test-device.c delete mode 100644 src/config/tests/nm-test-device.h delete mode 100644 src/config/tests/test-config.c create mode 100644 src/devices/bluetooth/nm-bluez5-dun.c create mode 100644 src/devices/bluetooth/nm-bluez5-dun.h create mode 100644 src/devices/bluetooth/nm-bt-error.c create mode 100644 src/devices/bluetooth/nm-bt-error.h create mode 100644 src/devices/nm-device-ethernet-utils.c create mode 100644 src/devices/nm-device-ethernet-utils.h create mode 100644 src/devices/nm-device-logging.h delete mode 100644 src/devices/nm-device-team.c delete mode 100644 src/devices/nm-device-team.h create mode 100644 src/devices/team/Makefile.am create mode 100644 src/devices/team/Makefile.in create mode 100644 src/devices/team/exports.ver create mode 100644 src/devices/team/nm-device-team-glue.h create mode 100644 src/devices/team/nm-device-team.c create mode 100644 src/devices/team/nm-device-team.h create mode 100644 src/devices/team/nm-team-enum-types.c create mode 100644 src/devices/team/nm-team-enum-types.h create mode 100644 src/devices/team/nm-team-factory.c create mode 100644 src/devices/team/nm-team-factory.h delete mode 100644 src/devices/wwan/README delete mode 100644 src/devices/wwan/nm-modem-old-types.h delete mode 100644 src/devices/wwan/nm-modem-old.c delete mode 100644 src/devices/wwan/nm-modem-old.h create mode 100644 src/dhcp-manager/nm-dhcp-listener.c create mode 100644 src/dhcp-manager/nm-dhcp-listener.h create mode 100644 src/dhcp-manager/nm-dhcp-systemd.c create mode 100644 src/dhcp-manager/nm-dhcp-systemd.h create mode 100644 src/dhcp-manager/nm-dhcp-utils.c create mode 100644 src/dhcp-manager/nm-dhcp-utils.h create mode 100644 src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c create mode 100644 src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/async.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/fileio.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/fileio.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/list.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/macro.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/strv.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/strv.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/time-util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/time-util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/utf8.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/utf8.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/util.c create mode 100644 src/dhcp-manager/systemd-dhcp/src/shared/util.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h create mode 100644 src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h create mode 100644 src/dhcp-manager/tests/test-dhcp-utils.c delete mode 100644 src/firewall-manager/nm-firewall-manager.c delete mode 100644 src/firewall-manager/nm-firewall-manager.h delete mode 100644 src/logging/nm-logging.c delete mode 100644 src/logging/nm-logging.h create mode 100644 src/main-utils.c create mode 100644 src/main-utils.h create mode 100644 src/nm-auth-manager.c create mode 100644 src/nm-auth-manager.h create mode 100644 src/nm-auth-utils.c create mode 100644 src/nm-auth-utils.h create mode 100644 src/nm-config.c create mode 100644 src/nm-config.h create mode 100644 src/nm-default-route-manager.c create mode 100644 src/nm-default-route-manager.h delete mode 100644 src/nm-device-team-glue.h create mode 100644 src/nm-firewall-manager.c create mode 100644 src/nm-firewall-manager.h create mode 100644 src/nm-iface-helper.c create mode 100644 src/nm-logging.c create mode 100644 src/nm-logging.h delete mode 100644 src/nm-manager-auth.c delete mode 100644 src/nm-manager-auth.h create mode 100644 src/nm-posix-signals.c create mode 100644 src/nm-posix-signals.h delete mode 100644 src/posix-signals/nm-posix-signals.c delete mode 100644 src/posix-signals/nm-posix-signals.h delete mode 100644 src/settings/nm-settings-error.c delete mode 100644 src/settings/nm-settings-error.h delete mode 100644 src/settings/nm-settings-utils.c delete mode 100644 src/settings/nm-settings-utils.h delete mode 100644 src/settings/plugins/example/errors.c create mode 100644 src/settings/plugins/ibft/Makefile.am create mode 100644 src/settings/plugins/ibft/Makefile.in create mode 100644 src/settings/plugins/ibft/nm-ibft-connection.c create mode 100644 src/settings/plugins/ibft/nm-ibft-connection.h create mode 100644 src/settings/plugins/ibft/plugin.c create mode 100644 src/settings/plugins/ibft/plugin.h create mode 100644 src/settings/plugins/ibft/reader.c create mode 100644 src/settings/plugins/ibft/reader.h create mode 100644 src/settings/plugins/ibft/tests/Makefile.am create mode 100644 src/settings/plugins/ibft/tests/Makefile.in create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns1 create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns2 create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-entry create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-gateway create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-ipaddr create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-bad-record create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-dhcp create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-static create mode 100755 src/settings/plugins/ibft/tests/iscsiadm-test-vlan create mode 100644 src/settings/plugins/ibft/tests/test-ibft.c delete mode 100644 src/settings/plugins/ifcfg-rh/errors.c delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp delete mode 100755 src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp delete mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-misc-variables create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-trailing-spaces create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch create mode 100644 src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch delete mode 100644 src/settings/plugins/ifnet/errors.c delete mode 100644 src/settings/plugins/ifnet/errors.h delete mode 100644 src/settings/plugins/keyfile/errors.c create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 create mode 100644 src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 delete mode 100644 src/settings/tests/Makefile.am delete mode 100644 src/settings/tests/Makefile.in delete mode 100644 src/settings/tests/test-wired-defname.c create mode 100644 src/tests/config/Makefile.am create mode 100644 src/tests/config/Makefile.in create mode 100644 src/tests/config/NetworkManager.conf create mode 100644 src/tests/config/bad.conf create mode 100644 src/tests/config/conf.d/00-overrides.conf create mode 100644 src/tests/config/conf.d/10-more.conf create mode 100644 src/tests/config/conf.d/90-last.conf create mode 100644 src/tests/config/nm-test-device.c create mode 100644 src/tests/config/nm-test-device.h create mode 100644 src/tests/config/test-config.c delete mode 100644 src/tests/test-dhcp-options.c create mode 100644 src/tests/test-general-with-expect.c create mode 100644 src/tests/test-wired-defname.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2929e18c..808e59eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,43 +5,121 @@ include $(GLIB_MAKEFILE) SUBDIRS = \ . \ devices/adsl \ - devices/wwan \ - devices/bluetooth \ - devices/wifi \ + devices/wifi \ dhcp-manager \ ppp-manager \ settings/plugins +if WITH_MODEM_MANAGER_1 +SUBDIRS += \ + devices/wwan \ + devices/bluetooth +endif + if WITH_WIMAX SUBDIRS += devices/wimax endif +if WITH_TEAMDCTL +SUBDIRS += devices/team +endif + if ENABLE_TESTS SUBDIRS += \ - config/tests \ dhcp-manager/tests \ dnsmasq-manager/tests \ platform \ rdisc \ - settings/tests \ supplicant-manager/tests \ tests endif AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I${top_srcdir}/libgsystem \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/callouts \ + -DPREFIX=\"$(prefix)\" \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE # add each subdirectory that contains a libNM source file. $(sort) is being used # primarily for its side effect of removing duplicates. AM_CPPFLAGS += $(foreach d,$(sort $(dir $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) +noinst_LTLIBRARIES = \ + libNetworkManager.la \ + libnm-iface-helper.la \ + libsystemd-dhcp.la + +###################### +# libsystemd-dhcp +###################### + +SYSTEMD_DHCP_CFLAGS = \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/systemd \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/libsystemd-network \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/shared \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp + +libsystemd_dhcp_la_SOURCES = \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c \ + dhcp-manager/systemd-dhcp/src/shared/async.h \ + dhcp-manager/systemd-dhcp/src/shared/time-util.h \ + dhcp-manager/systemd-dhcp/src/shared/siphash24.h \ + dhcp-manager/systemd-dhcp/src/shared/time-util.c \ + dhcp-manager/systemd-dhcp/src/shared/socket-util.h \ + dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h \ + dhcp-manager/systemd-dhcp/src/shared/macro.h \ + dhcp-manager/systemd-dhcp/src/shared/refcnt.h \ + dhcp-manager/systemd-dhcp/src/shared/util.c \ + dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c \ + dhcp-manager/systemd-dhcp/src/shared/siphash24.c \ + dhcp-manager/systemd-dhcp/src/shared/util.h \ + dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h \ + dhcp-manager/systemd-dhcp/src/shared/list.h \ + dhcp-manager/systemd-dhcp/src/shared/fileio.h \ + dhcp-manager/systemd-dhcp/src/shared/fileio.c \ + dhcp-manager/systemd-dhcp/src/shared/strv.h \ + dhcp-manager/systemd-dhcp/src/shared/strv.c \ + dhcp-manager/systemd-dhcp/src/shared/unaligned.h \ + dhcp-manager/systemd-dhcp/src/shared/utf8.h \ + dhcp-manager/systemd-dhcp/src/shared/utf8.c \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-event.h \ + dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h \ + dhcp-manager/systemd-dhcp/nm-sd-adapt.h \ + dhcp-manager/systemd-dhcp/nm-sd-adapt.c + +libsystemd_dhcp_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + $(SYSTEMD_DHCP_CFLAGS) \ + $(GLIB_CFLAGS) + +libsystemd_dhcp_la_LIBADD = \ + $(GLIB_LIBS) + ########################################### # NetworkManager ########################################### @@ -49,56 +127,71 @@ AM_CPPFLAGS += $(foreach d,$(sort $(dir $(libNetworkManager_la_SOURCES))),-I$(to sbin_PROGRAMS = NetworkManager NetworkManager_SOURCES = \ + $(nm_device_sources) $(nm_device_headers) \ + $(nm_dhcp_client_sources) $(nm_dhcp_client_headers) \ + main-utils.c \ + main-utils.h \ main.c -NetworkManager_LDADD = libNetworkManager.la $(top_builddir)/libgsystem.la $(LIBNDP_LIBS) +NetworkManager_LDADD = libNetworkManager.la -noinst_LTLIBRARIES = libNetworkManager.la - -nm_sources = \ - config/nm-config.c \ - config/nm-config.h \ - config/nm-config-device.c \ - config/nm-config-device.h \ - \ - devices/nm-device.c \ - devices/nm-device.h \ +nm_device_sources = \ devices/nm-device-bond.c \ - devices/nm-device-bond.h \ devices/nm-device-bridge.c \ - devices/nm-device-bridge.h \ devices/nm-device-ethernet.c \ - devices/nm-device-ethernet.h \ - devices/nm-device-factory.c \ - devices/nm-device-factory.h \ - devices/nm-device-generic.c \ - devices/nm-device-generic.h \ devices/nm-device-gre.c \ - devices/nm-device-gre.h \ devices/nm-device-infiniband.c \ - devices/nm-device-infiniband.h \ devices/nm-device-macvlan.c \ - devices/nm-device-macvlan.h \ - devices/nm-device-private.h \ - devices/nm-device-team.c \ - devices/nm-device-team.h \ devices/nm-device-tun.c \ - devices/nm-device-tun.h \ devices/nm-device-veth.c \ - devices/nm-device-veth.h \ devices/nm-device-vlan.c \ - devices/nm-device-vlan.h \ devices/nm-device-vxlan.c \ - devices/nm-device-vxlan.h \ - \ - dhcp-manager/nm-dhcp-client.c \ - dhcp-manager/nm-dhcp-client.h \ + $(NULL) + +nm_device_headers = \ + devices/nm-device-bond.h \ + devices/nm-device-bridge.h \ + devices/nm-device-ethernet.h \ + devices/nm-device-gre.h \ + devices/nm-device-infiniband.h \ + devices/nm-device-macvlan.h \ + devices/nm-device-tun.h \ + devices/nm-device-veth.h \ + devices/nm-device-vlan.h \ + devices/nm-device-vxlan.h + +nm_dhcp_client_sources = \ dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhclient.h \ dhcp-manager/nm-dhcp-dhclient-utils.c \ - dhcp-manager/nm-dhcp-dhclient-utils.h \ dhcp-manager/nm-dhcp-dhcpcd.c \ + dhcp-manager/nm-dhcp-systemd.c + +nm_dhcp_client_headers = \ + dhcp-manager/nm-dhcp-dhclient.h \ + dhcp-manager/nm-dhcp-dhclient-utils.h \ dhcp-manager/nm-dhcp-dhcpcd.h \ + dhcp-manager/nm-dhcp-systemd.h + +nm_sources = \ + $(nm_device_headers) \ + $(nm_dhcp_client_headers) \ + devices/nm-device.c \ + devices/nm-device.h \ + devices/nm-device-ethernet-utils.c \ + devices/nm-device-ethernet-utils.h \ + devices/nm-device-factory.c \ + devices/nm-device-factory.h \ + devices/nm-device-generic.c \ + devices/nm-device-generic.h \ + devices/nm-device-logging.h \ + devices/nm-device-private.h \ + \ + dhcp-manager/nm-dhcp-client.c \ + dhcp-manager/nm-dhcp-client.h \ + dhcp-manager/nm-dhcp-utils.c \ + dhcp-manager/nm-dhcp-utils.h \ + dhcp-manager/nm-dhcp-listener.c \ + dhcp-manager/nm-dhcp-listener.h \ dhcp-manager/nm-dhcp-manager.c \ dhcp-manager/nm-dhcp-manager.h \ \ @@ -118,12 +211,6 @@ nm_sources = \ dnsmasq-manager/nm-dnsmasq-utils.c \ dnsmasq-manager/nm-dnsmasq-utils.h \ \ - firewall-manager/nm-firewall-manager.c \ - firewall-manager/nm-firewall-manager.h \ - \ - logging/nm-logging.c \ - logging/nm-logging.h \ - \ platform/nm-fake-platform.c \ platform/nm-fake-platform.h \ platform/nm-linux-platform.c \ @@ -143,9 +230,6 @@ nm_sources = \ rdisc/nm-rdisc.c \ rdisc/nm-rdisc.h \ \ - posix-signals/nm-posix-signals.c \ - posix-signals/nm-posix-signals.h \ - \ ppp-manager/nm-ppp-manager.c \ ppp-manager/nm-ppp-manager.h \ ppp-manager/nm-ppp-status.h \ @@ -158,17 +242,12 @@ nm_sources = \ settings/nm-secret-agent.h \ settings/nm-settings-connection.c \ settings/nm-settings-connection.h \ - settings/nm-settings-error.c \ - settings/nm-settings-error.h \ - settings/nm-settings-utils.c \ - settings/nm-settings-utils.h \ settings/nm-settings.c \ settings/nm-settings.h \ settings/nm-system-config-interface.c \ settings/nm-system-config-interface.h \ \ settings/plugins/keyfile/common.h \ - settings/plugins/keyfile/errors.c \ settings/plugins/keyfile/nm-keyfile-connection.c \ settings/plugins/keyfile/nm-keyfile-connection.h \ settings/plugins/keyfile/plugin.c \ @@ -203,6 +282,8 @@ nm_sources = \ nm-activation-request.h \ nm-active-connection.c \ nm-active-connection.h \ + nm-config.c \ + nm-config.h \ nm-connection-provider.c \ nm-connection-provider.h \ nm-connectivity.c \ @@ -211,6 +292,8 @@ nm_sources = \ nm-dbus-manager.h \ nm-dcb.c \ nm-dcb.h \ + nm-default-route-manager.c \ + nm-default-route-manager.h \ nm-dhcp4-config.c \ nm-dhcp4-config.h \ nm-dhcp6-config.c \ @@ -219,18 +302,26 @@ nm_sources = \ nm-dispatcher.h \ nm-enum-types.c \ nm-enum-types.h \ + nm-firewall-manager.c \ + nm-firewall-manager.h \ nm-ip4-config.c \ nm-ip4-config.h \ nm-ip6-config.c \ nm-ip6-config.h \ - nm-manager-auth.c \ - nm-manager-auth.h \ + nm-logging.c \ + nm-logging.h \ + nm-auth-manager.c \ + nm-auth-manager.h \ nm-auth-subject.c \ nm-auth-subject.h \ + nm-auth-utils.c \ + nm-auth-utils.h \ nm-manager.c \ nm-manager.h \ nm-policy.c \ nm-policy.h \ + nm-posix-signals.c \ + nm-posix-signals.h \ nm-properties-changed-signal.c \ nm-properties-changed-signal.h \ nm-rfkill-manager.c \ @@ -268,7 +359,7 @@ endif GLIB_GENERATED = nm-enum-types.h nm-enum-types.c -GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include \n' GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM nm_enum_types_sources = $(nm_sources) @@ -292,7 +383,6 @@ glue_sources = \ nm-device-gre-glue.h \ nm-device-infiniband-glue.h \ nm-device-macvlan-glue.h \ - nm-device-team-glue.h \ nm-device-tun-glue.h \ nm-device-veth-glue.h \ nm-device-vlan-glue.h \ @@ -320,8 +410,8 @@ AM_CPPFLAGS += \ $(LIBNL_CFLAGS) \ $(LIBNDP_CFLAGS) \ $(LIBSOUP_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ + $(SYSTEMD_DHCP_CFLAGS) \ \ -DBINDIR=\"$(bindir)\" \ -DDATADIR=\"$(datadir)\" \ @@ -347,35 +437,109 @@ if SESSION_TRACKING_CK AM_CPPFLAGS += -DCKDB_PATH=\"${CKDB_PATH}\" endif -if WITH_TEAMDCTL -AM_CPPFLAGS += ${LIBTEAMDCTL_CFLAGS} -endif - libNetworkManager_la_SOURCES = \ $(nm_sources) \ $(glue_sources) libNetworkManager_la_LIBADD = \ - $(top_builddir)/libgsystem.la \ - $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-core/libnm-core.la \ + libsystemd-dhcp.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(GUDEV_LIBS) \ $(LIBNL_LIBS) \ - $(POLKIT_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ + $(LIBNDP_LIBS) \ $(LIBDL) \ $(LIBM) -if WITH_CONCHECK +if WITH_LIBSOUP libNetworkManager_la_LIBADD += $(LIBSOUP_LIBS) endif -if WITH_TEAMDCTL -libNetworkManager_la_LIBADD += $(LIBTEAMDCTL_LIBS) +NetworkManager_LDFLAGS = -rdynamic + +###################### + +libnm_iface_helper_la_SOURCES = \ + dhcp-manager/nm-dhcp-client.c \ + dhcp-manager/nm-dhcp-client.h \ + dhcp-manager/nm-dhcp-utils.c \ + dhcp-manager/nm-dhcp-utils.h \ + dhcp-manager/nm-dhcp-manager.c \ + dhcp-manager/nm-dhcp-manager.h \ + \ + platform/nm-linux-platform.c \ + platform/nm-linux-platform.h \ + platform/nm-platform.c \ + platform/nm-platform.h \ + platform/wifi/wifi-utils-nl80211.c \ + platform/wifi/wifi-utils-nl80211.h \ + platform/wifi/wifi-utils-private.h \ + platform/wifi/wifi-utils.c \ + platform/wifi/wifi-utils.h \ + \ + rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h \ + rdisc/nm-lndp-rdisc.c \ + rdisc/nm-lndp-rdisc.h \ + rdisc/nm-rdisc.c \ + rdisc/nm-rdisc.h \ + \ + nm-ip4-config.c \ + nm-ip4-config.h \ + nm-ip6-config.c \ + nm-ip6-config.h \ + \ + nm-enum-types.c \ + nm-enum-types.h \ + nm-logging.c \ + nm-logging.h \ + nm-posix-signals.c \ + nm-posix-signals.h \ + NetworkManagerUtils.c \ + NetworkManagerUtils.h + +if WITH_WEXT +libnm_iface_helper_la_SOURCES += \ + platform/wifi/wifi-utils-wext.c \ + platform/wifi/wifi-utils-wext.h endif -NetworkManager_LDFLAGS = -rdynamic +libnm_iface_helper_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + libsystemd-dhcp.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GUDEV_LIBS) \ + $(LIBNL_LIBS) \ + $(LIBNDP_LIBS) \ + $(LIBDL) \ + $(LIBM) + +libexec_PROGRAMS = nm-iface-helper + +nm_iface_helper_SOURCES = \ + dhcp-manager/nm-dhcp-systemd.h \ + dhcp-manager/nm-dhcp-systemd.c \ + nm-iface-helper.c \ + main-utils.c \ + main-utils.h + +nm_iface_helper_LDADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + libsystemd-dhcp.la \ + libnm-iface-helper.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GUDEV_LIBS) \ + $(LIBNL_LIBS) \ + $(LIBNDP_LIBS) \ + $(LIBM) + +nm_iface_helper_LDFLAGS = -rdynamic + +###################### dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = org.freedesktop.NetworkManager.conf diff --git a/src/Makefile.in b/src/Makefile.in index 6aa8aa0a..6828f69c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -80,34 +80,40 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_WIMAX_TRUE@am__append_1 = devices/wimax -@ENABLE_TESTS_TRUE@am__append_2 = \ -@ENABLE_TESTS_TRUE@ config/tests \ +@WITH_MODEM_MANAGER_1_TRUE@am__append_1 = \ +@WITH_MODEM_MANAGER_1_TRUE@ devices/wwan \ +@WITH_MODEM_MANAGER_1_TRUE@ devices/bluetooth + +@WITH_WIMAX_TRUE@am__append_2 = devices/wimax +@WITH_TEAMDCTL_TRUE@am__append_3 = devices/team +@ENABLE_TESTS_TRUE@am__append_4 = \ @ENABLE_TESTS_TRUE@ dhcp-manager/tests \ @ENABLE_TESTS_TRUE@ dnsmasq-manager/tests \ @ENABLE_TESTS_TRUE@ platform \ @ENABLE_TESTS_TRUE@ rdisc \ -@ENABLE_TESTS_TRUE@ settings/tests \ @ENABLE_TESTS_TRUE@ supplicant-manager/tests \ @ENABLE_TESTS_TRUE@ tests sbin_PROGRAMS = NetworkManager$(EXEEXT) -@SESSION_TRACKING_SYSTEMD_TRUE@am__append_3 = nm-session-monitor-systemd.c -@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_4 = nm-session-monitor-ck.c -@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_5 = nm-session-monitor-null.c -@SUSPEND_RESUME_SYSTEMD_TRUE@am__append_6 = nm-sleep-monitor-systemd.c +@SESSION_TRACKING_SYSTEMD_TRUE@am__append_5 = nm-session-monitor-systemd.c +@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_6 = nm-session-monitor-ck.c +@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__append_7 = nm-session-monitor-null.c +@SUSPEND_RESUME_SYSTEMD_TRUE@am__append_8 = nm-sleep-monitor-systemd.c # UPower suspend/resume used whenever systemd is not enabled -@SUSPEND_RESUME_SYSTEMD_FALSE@am__append_7 = nm-sleep-monitor-upower.c -@WITH_WEXT_TRUE@am__append_8 = \ +@SUSPEND_RESUME_SYSTEMD_FALSE@am__append_9 = nm-sleep-monitor-upower.c +@WITH_WEXT_TRUE@am__append_10 = \ +@WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.c \ +@WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.h + +@WITH_WIMAX_TRUE@am__append_11 = devices/wimax/nm-device-wimax.h +@WITH_WIMAX_TRUE@am__append_12 = -I$(top_srcdir)/src/devices/wimax +@SESSION_TRACKING_CK_TRUE@am__append_13 = -DCKDB_PATH=\"${CKDB_PATH}\" +@WITH_LIBSOUP_TRUE@am__append_14 = $(LIBSOUP_LIBS) +@WITH_WEXT_TRUE@am__append_15 = \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.c \ @WITH_WEXT_TRUE@ platform/wifi/wifi-utils-wext.h -@WITH_WIMAX_TRUE@am__append_9 = devices/wimax/nm-device-wimax.h -@WITH_WIMAX_TRUE@am__append_10 = -I$(top_srcdir)/src/devices/wimax -@SESSION_TRACKING_CK_TRUE@am__append_11 = -DCKDB_PATH=\"${CKDB_PATH}\" -@WITH_TEAMDCTL_TRUE@am__append_12 = ${LIBTEAMDCTL_CFLAGS} -@WITH_CONCHECK_TRUE@am__append_13 = $(LIBSOUP_LIBS) -@WITH_TEAMDCTL_TRUE@am__append_14 = $(LIBTEAMDCTL_LIBS) +libexec_PROGRAMS = nm-iface-helper$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -133,51 +139,41 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = -@WITH_CONCHECK_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -@WITH_TEAMDCTL_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) -libNetworkManager_la_DEPENDENCIES = $(top_builddir)/libgsystem.la \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \ +@WITH_LIBSOUP_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libNetworkManager_la_DEPENDENCIES = \ + $(top_builddir)/libnm-core/libnm-core.la libsystemd-dhcp.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_3) -am__libNetworkManager_la_SOURCES_DIST = config/nm-config.c \ - config/nm-config.h config/nm-config-device.c \ - config/nm-config-device.h devices/nm-device.c \ - devices/nm-device.h devices/nm-device-bond.c \ - devices/nm-device-bond.h devices/nm-device-bridge.c \ - devices/nm-device-bridge.h devices/nm-device-ethernet.c \ - devices/nm-device-ethernet.h devices/nm-device-factory.c \ - devices/nm-device-factory.h devices/nm-device-generic.c \ - devices/nm-device-generic.h devices/nm-device-gre.c \ - devices/nm-device-gre.h devices/nm-device-infiniband.c \ - devices/nm-device-infiniband.h devices/nm-device-macvlan.c \ - devices/nm-device-macvlan.h devices/nm-device-private.h \ - devices/nm-device-team.c devices/nm-device-team.h \ - devices/nm-device-tun.c devices/nm-device-tun.h \ - devices/nm-device-veth.c devices/nm-device-veth.h \ - devices/nm-device-vlan.c devices/nm-device-vlan.h \ - devices/nm-device-vxlan.c devices/nm-device-vxlan.h \ - dhcp-manager/nm-dhcp-client.c dhcp-manager/nm-dhcp-client.h \ - dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhclient.h \ - dhcp-manager/nm-dhcp-dhclient-utils.c \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am__libNetworkManager_la_SOURCES_DIST = devices/nm-device-bond.h \ + devices/nm-device-bridge.h devices/nm-device-ethernet.h \ + devices/nm-device-gre.h devices/nm-device-infiniband.h \ + devices/nm-device-macvlan.h devices/nm-device-tun.h \ + devices/nm-device-veth.h devices/nm-device-vlan.h \ + devices/nm-device-vxlan.h dhcp-manager/nm-dhcp-dhclient.h \ dhcp-manager/nm-dhcp-dhclient-utils.h \ - dhcp-manager/nm-dhcp-dhcpcd.c dhcp-manager/nm-dhcp-dhcpcd.h \ - dhcp-manager/nm-dhcp-manager.c dhcp-manager/nm-dhcp-manager.h \ - dns-manager/nm-dns-dnsmasq.c dns-manager/nm-dns-dnsmasq.h \ - dns-manager/nm-dns-unbound.c dns-manager/nm-dns-unbound.h \ - dns-manager/nm-dns-manager.c dns-manager/nm-dns-manager.h \ - dns-manager/nm-dns-plugin.c dns-manager/nm-dns-plugin.h \ - dns-manager/nm-dns-utils.c dns-manager/nm-dns-utils.h \ + dhcp-manager/nm-dhcp-dhcpcd.h dhcp-manager/nm-dhcp-systemd.h \ + devices/nm-device.c devices/nm-device.h \ + devices/nm-device-ethernet-utils.c \ + devices/nm-device-ethernet-utils.h devices/nm-device-factory.c \ + devices/nm-device-factory.h devices/nm-device-generic.c \ + devices/nm-device-generic.h devices/nm-device-logging.h \ + devices/nm-device-private.h dhcp-manager/nm-dhcp-client.c \ + dhcp-manager/nm-dhcp-client.h dhcp-manager/nm-dhcp-utils.c \ + dhcp-manager/nm-dhcp-utils.h dhcp-manager/nm-dhcp-listener.c \ + dhcp-manager/nm-dhcp-listener.h dhcp-manager/nm-dhcp-manager.c \ + dhcp-manager/nm-dhcp-manager.h dns-manager/nm-dns-dnsmasq.c \ + dns-manager/nm-dns-dnsmasq.h dns-manager/nm-dns-unbound.c \ + dns-manager/nm-dns-unbound.h dns-manager/nm-dns-manager.c \ + dns-manager/nm-dns-manager.h dns-manager/nm-dns-plugin.c \ + dns-manager/nm-dns-plugin.h dns-manager/nm-dns-utils.c \ + dns-manager/nm-dns-utils.h \ dnsmasq-manager/nm-dnsmasq-manager.c \ dnsmasq-manager/nm-dnsmasq-manager.h \ dnsmasq-manager/nm-dnsmasq-utils.c \ - dnsmasq-manager/nm-dnsmasq-utils.h \ - firewall-manager/nm-firewall-manager.c \ - firewall-manager/nm-firewall-manager.h logging/nm-logging.c \ - logging/nm-logging.h platform/nm-fake-platform.c \ + dnsmasq-manager/nm-dnsmasq-utils.h platform/nm-fake-platform.c \ platform/nm-fake-platform.h platform/nm-linux-platform.c \ platform/nm-linux-platform.h platform/nm-platform.c \ platform/nm-platform.h platform/wifi/wifi-utils-nl80211.c \ @@ -186,20 +182,15 @@ am__libNetworkManager_la_SOURCES_DIST = config/nm-config.c \ platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ - posix-signals/nm-posix-signals.c \ - posix-signals/nm-posix-signals.h ppp-manager/nm-ppp-manager.c \ - ppp-manager/nm-ppp-manager.h ppp-manager/nm-ppp-status.h \ - settings/nm-agent-manager.c settings/nm-agent-manager.h \ - settings/nm-inotify-helper.c settings/nm-inotify-helper.h \ - settings/nm-secret-agent.c settings/nm-secret-agent.h \ - settings/nm-settings-connection.c \ - settings/nm-settings-connection.h settings/nm-settings-error.c \ - settings/nm-settings-error.h settings/nm-settings-utils.c \ - settings/nm-settings-utils.h settings/nm-settings.c \ + ppp-manager/nm-ppp-manager.c ppp-manager/nm-ppp-manager.h \ + ppp-manager/nm-ppp-status.h settings/nm-agent-manager.c \ + settings/nm-agent-manager.h settings/nm-inotify-helper.c \ + settings/nm-inotify-helper.h settings/nm-secret-agent.c \ + settings/nm-secret-agent.h settings/nm-settings-connection.c \ + settings/nm-settings-connection.h settings/nm-settings.c \ settings/nm-settings.h settings/nm-system-config-interface.c \ settings/nm-system-config-interface.h \ settings/plugins/keyfile/common.h \ - settings/plugins/keyfile/errors.c \ settings/plugins/keyfile/nm-keyfile-connection.c \ settings/plugins/keyfile/nm-keyfile-connection.h \ settings/plugins/keyfile/plugin.c \ @@ -226,20 +217,23 @@ am__libNetworkManager_la_SOURCES_DIST = config/nm-config.c \ vpn-manager/nm-vpn-manager.h vpn-manager/nm-vpn-service.c \ vpn-manager/nm-vpn-service.h nm-activation-request.c \ nm-activation-request.h nm-active-connection.c \ - nm-active-connection.h nm-connection-provider.c \ - nm-connection-provider.h nm-connectivity.c nm-connectivity.h \ - nm-dbus-manager.c nm-dbus-manager.h nm-dcb.c nm-dcb.h \ - nm-dhcp4-config.c nm-dhcp4-config.h nm-dhcp6-config.c \ - nm-dhcp6-config.h nm-dispatcher.c nm-dispatcher.h \ - nm-enum-types.c nm-enum-types.h nm-ip4-config.c \ - nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h \ - nm-manager-auth.c nm-manager-auth.h nm-auth-subject.c \ - nm-auth-subject.h nm-manager.c nm-manager.h nm-policy.c \ - nm-policy.h nm-properties-changed-signal.c \ - nm-properties-changed-signal.h nm-rfkill-manager.c \ - nm-rfkill-manager.h nm-session-monitor.h nm-session-utils.c \ - nm-session-utils.h nm-sleep-monitor.h nm-types.h \ - NetworkManagerUtils.c NetworkManagerUtils.h \ + nm-active-connection.h nm-config.c nm-config.h \ + nm-connection-provider.c nm-connection-provider.h \ + nm-connectivity.c nm-connectivity.h nm-dbus-manager.c \ + nm-dbus-manager.h nm-dcb.c nm-dcb.h nm-default-route-manager.c \ + nm-default-route-manager.h nm-dhcp4-config.c nm-dhcp4-config.h \ + nm-dhcp6-config.c nm-dhcp6-config.h nm-dispatcher.c \ + nm-dispatcher.h nm-enum-types.c nm-enum-types.h \ + nm-firewall-manager.c nm-firewall-manager.h nm-ip4-config.c \ + nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h nm-logging.c \ + nm-logging.h nm-auth-manager.c nm-auth-manager.h \ + nm-auth-subject.c nm-auth-subject.h nm-auth-utils.c \ + nm-auth-utils.h nm-manager.c nm-manager.h nm-policy.c \ + nm-policy.h nm-posix-signals.c nm-posix-signals.h \ + nm-properties-changed-signal.c nm-properties-changed-signal.h \ + nm-rfkill-manager.c nm-rfkill-manager.h nm-session-monitor.h \ + nm-session-utils.c nm-session-utils.h nm-sleep-monitor.h \ + nm-types.h NetworkManagerUtils.c NetworkManagerUtils.h \ nm-session-monitor-systemd.c nm-session-monitor-ck.c \ nm-session-monitor-null.c nm-sleep-monitor-systemd.c \ nm-sleep-monitor-upower.c platform/wifi/wifi-utils-wext.c \ @@ -249,71 +243,137 @@ am__libNetworkManager_la_SOURCES_DIST = config/nm-config.c \ nm-device-ethernet-glue.h nm-device-generic-glue.h \ nm-device-glue.h nm-device-gre-glue.h \ nm-device-infiniband-glue.h nm-device-macvlan-glue.h \ - nm-device-team-glue.h nm-device-tun-glue.h \ - nm-device-veth-glue.h nm-device-vlan-glue.h \ - nm-device-vxlan-glue.h nm-dhcp4-config-glue.h \ - nm-dhcp6-config-glue.h nm-ip4-config-glue.h \ - nm-ip6-config-glue.h nm-manager-glue.h nm-ppp-manager-glue.h \ - nm-settings-connection-glue.h nm-settings-glue.h \ - nm-vpn-connection-glue.h -@SESSION_TRACKING_SYSTEMD_TRUE@am__objects_1 = \ + nm-device-tun-glue.h nm-device-veth-glue.h \ + nm-device-vlan-glue.h nm-device-vxlan-glue.h \ + nm-dhcp4-config-glue.h nm-dhcp6-config-glue.h \ + nm-ip4-config-glue.h nm-ip6-config-glue.h nm-manager-glue.h \ + nm-ppp-manager-glue.h nm-settings-connection-glue.h \ + nm-settings-glue.h nm-vpn-connection-glue.h +am__objects_1 = +@SESSION_TRACKING_SYSTEMD_TRUE@am__objects_2 = \ @SESSION_TRACKING_SYSTEMD_TRUE@ nm-session-monitor-systemd.lo -@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_2 = nm-session-monitor-ck.lo -@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_3 = nm-session-monitor-null.lo -@SUSPEND_RESUME_SYSTEMD_TRUE@am__objects_4 = \ +@SESSION_TRACKING_CK_TRUE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_3 = nm-session-monitor-ck.lo +@SESSION_TRACKING_CK_FALSE@@SESSION_TRACKING_SYSTEMD_FALSE@am__objects_4 = nm-session-monitor-null.lo +@SUSPEND_RESUME_SYSTEMD_TRUE@am__objects_5 = \ @SUSPEND_RESUME_SYSTEMD_TRUE@ nm-sleep-monitor-systemd.lo -@SUSPEND_RESUME_SYSTEMD_FALSE@am__objects_5 = \ +@SUSPEND_RESUME_SYSTEMD_FALSE@am__objects_6 = \ @SUSPEND_RESUME_SYSTEMD_FALSE@ nm-sleep-monitor-upower.lo -@WITH_WEXT_TRUE@am__objects_6 = wifi-utils-wext.lo -am__objects_7 = nm-config.lo nm-config-device.lo nm-device.lo \ - nm-device-bond.lo nm-device-bridge.lo nm-device-ethernet.lo \ - nm-device-factory.lo nm-device-generic.lo nm-device-gre.lo \ - nm-device-infiniband.lo nm-device-macvlan.lo nm-device-team.lo \ - nm-device-tun.lo nm-device-veth.lo nm-device-vlan.lo \ - nm-device-vxlan.lo nm-dhcp-client.lo nm-dhcp-dhclient.lo \ - nm-dhcp-dhclient-utils.lo nm-dhcp-dhcpcd.lo nm-dhcp-manager.lo \ - nm-dns-dnsmasq.lo nm-dns-unbound.lo nm-dns-manager.lo \ - nm-dns-plugin.lo nm-dns-utils.lo nm-dnsmasq-manager.lo \ - nm-dnsmasq-utils.lo nm-firewall-manager.lo nm-logging.lo \ +@WITH_WEXT_TRUE@am__objects_7 = wifi-utils-wext.lo +am__objects_8 = $(am__objects_1) $(am__objects_1) nm-device.lo \ + nm-device-ethernet-utils.lo nm-device-factory.lo \ + nm-device-generic.lo nm-dhcp-client.lo nm-dhcp-utils.lo \ + nm-dhcp-listener.lo nm-dhcp-manager.lo nm-dns-dnsmasq.lo \ + nm-dns-unbound.lo nm-dns-manager.lo nm-dns-plugin.lo \ + nm-dns-utils.lo nm-dnsmasq-manager.lo nm-dnsmasq-utils.lo \ nm-fake-platform.lo nm-linux-platform.lo nm-platform.lo \ wifi-utils-nl80211.lo wifi-utils.lo nm-fake-rdisc.lo \ - nm-lndp-rdisc.lo nm-rdisc.lo nm-posix-signals.lo \ - nm-ppp-manager.lo nm-agent-manager.lo nm-inotify-helper.lo \ - nm-secret-agent.lo nm-settings-connection.lo \ - nm-settings-error.lo nm-settings-utils.lo nm-settings.lo \ - nm-system-config-interface.lo errors.lo \ - nm-keyfile-connection.lo plugin.lo reader.lo utils.lo \ - writer.lo nm-supplicant-config.lo nm-supplicant-interface.lo \ - nm-supplicant-manager.lo nm-supplicant-settings-verify.lo \ - nm-call-store.lo nm-vpn-connection.lo nm-vpn-manager.lo \ - nm-vpn-service.lo nm-activation-request.lo \ - nm-active-connection.lo nm-connection-provider.lo \ - nm-connectivity.lo nm-dbus-manager.lo nm-dcb.lo \ + nm-lndp-rdisc.lo nm-rdisc.lo nm-ppp-manager.lo \ + nm-agent-manager.lo nm-inotify-helper.lo nm-secret-agent.lo \ + nm-settings-connection.lo nm-settings.lo \ + nm-system-config-interface.lo nm-keyfile-connection.lo \ + plugin.lo reader.lo utils.lo writer.lo nm-supplicant-config.lo \ + nm-supplicant-interface.lo nm-supplicant-manager.lo \ + nm-supplicant-settings-verify.lo nm-call-store.lo \ + nm-vpn-connection.lo nm-vpn-manager.lo nm-vpn-service.lo \ + nm-activation-request.lo nm-active-connection.lo nm-config.lo \ + nm-connection-provider.lo nm-connectivity.lo \ + nm-dbus-manager.lo nm-dcb.lo nm-default-route-manager.lo \ nm-dhcp4-config.lo nm-dhcp6-config.lo nm-dispatcher.lo \ - nm-enum-types.lo nm-ip4-config.lo nm-ip6-config.lo \ - nm-manager-auth.lo nm-auth-subject.lo nm-manager.lo \ - nm-policy.lo nm-properties-changed-signal.lo \ + nm-enum-types.lo nm-firewall-manager.lo nm-ip4-config.lo \ + nm-ip6-config.lo nm-logging.lo nm-auth-manager.lo \ + nm-auth-subject.lo nm-auth-utils.lo nm-manager.lo nm-policy.lo \ + nm-posix-signals.lo nm-properties-changed-signal.lo \ nm-rfkill-manager.lo nm-session-utils.lo \ - NetworkManagerUtils.lo $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) $(am__objects_5) \ - $(am__objects_6) -am__objects_8 = -am_libNetworkManager_la_OBJECTS = $(am__objects_7) $(am__objects_8) + NetworkManagerUtils.lo $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) $(am__objects_5) $(am__objects_6) \ + $(am__objects_7) +am_libNetworkManager_la_OBJECTS = $(am__objects_8) $(am__objects_1) libNetworkManager_la_OBJECTS = $(am_libNetworkManager_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(dbusservicedir)" -PROGRAMS = $(sbin_PROGRAMS) -am_NetworkManager_OBJECTS = main.$(OBJEXT) +libnm_iface_helper_la_DEPENDENCIES = \ + $(top_builddir)/libnm-core/libnm-core.la libsystemd-dhcp.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__libnm_iface_helper_la_SOURCES_DIST = \ + dhcp-manager/nm-dhcp-client.c dhcp-manager/nm-dhcp-client.h \ + dhcp-manager/nm-dhcp-utils.c dhcp-manager/nm-dhcp-utils.h \ + dhcp-manager/nm-dhcp-manager.c dhcp-manager/nm-dhcp-manager.h \ + platform/nm-linux-platform.c platform/nm-linux-platform.h \ + platform/nm-platform.c platform/nm-platform.h \ + platform/wifi/wifi-utils-nl80211.c \ + platform/wifi/wifi-utils-nl80211.h \ + platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ + platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ + nm-ip4-config.c nm-ip4-config.h nm-ip6-config.c \ + nm-ip6-config.h nm-enum-types.c nm-enum-types.h nm-logging.c \ + nm-logging.h nm-posix-signals.c nm-posix-signals.h \ + NetworkManagerUtils.c NetworkManagerUtils.h \ + platform/wifi/wifi-utils-wext.c \ + platform/wifi/wifi-utils-wext.h +am_libnm_iface_helper_la_OBJECTS = nm-dhcp-client.lo nm-dhcp-utils.lo \ + nm-dhcp-manager.lo nm-linux-platform.lo nm-platform.lo \ + wifi-utils-nl80211.lo wifi-utils.lo nm-fake-rdisc.lo \ + nm-lndp-rdisc.lo nm-rdisc.lo nm-ip4-config.lo nm-ip6-config.lo \ + nm-enum-types.lo nm-logging.lo nm-posix-signals.lo \ + NetworkManagerUtils.lo $(am__objects_7) +libnm_iface_helper_la_OBJECTS = $(am_libnm_iface_helper_la_OBJECTS) +libsystemd_dhcp_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libsystemd_dhcp_la_OBJECTS = libsystemd_dhcp_la-dhcp-network.lo \ + libsystemd_dhcp_la-dhcp-packet.lo \ + libsystemd_dhcp_la-dhcp6-network.lo \ + libsystemd_dhcp_la-dhcp6-option.lo \ + libsystemd_dhcp_la-network-internal.lo \ + libsystemd_dhcp_la-sd-dhcp-lease.lo \ + libsystemd_dhcp_la-sd-dhcp-client.lo \ + libsystemd_dhcp_la-dhcp-option.lo \ + libsystemd_dhcp_la-sd-dhcp6-lease.lo \ + libsystemd_dhcp_la-sd-dhcp6-client.lo \ + libsystemd_dhcp_la-time-util.lo libsystemd_dhcp_la-util.lo \ + libsystemd_dhcp_la-in-addr-util.lo \ + libsystemd_dhcp_la-siphash24.lo libsystemd_dhcp_la-fileio.lo \ + libsystemd_dhcp_la-strv.lo libsystemd_dhcp_la-utf8.lo \ + libsystemd_dhcp_la-nm-sd-adapt.lo +libsystemd_dhcp_la_OBJECTS = $(am_libsystemd_dhcp_la_OBJECTS) +am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(dbusservicedir)" +PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS) +am__objects_9 = nm-device-bond.$(OBJEXT) nm-device-bridge.$(OBJEXT) \ + nm-device-ethernet.$(OBJEXT) nm-device-gre.$(OBJEXT) \ + nm-device-infiniband.$(OBJEXT) nm-device-macvlan.$(OBJEXT) \ + nm-device-tun.$(OBJEXT) nm-device-veth.$(OBJEXT) \ + nm-device-vlan.$(OBJEXT) nm-device-vxlan.$(OBJEXT) +am__objects_10 = nm-dhcp-dhclient.$(OBJEXT) \ + nm-dhcp-dhclient-utils.$(OBJEXT) nm-dhcp-dhcpcd.$(OBJEXT) \ + nm-dhcp-systemd.$(OBJEXT) +am_NetworkManager_OBJECTS = $(am__objects_9) $(am__objects_1) \ + $(am__objects_10) $(am__objects_1) main-utils.$(OBJEXT) \ + main.$(OBJEXT) NetworkManager_OBJECTS = $(am_NetworkManager_OBJECTS) -NetworkManager_DEPENDENCIES = libNetworkManager.la \ - $(top_builddir)/libgsystem.la $(am__DEPENDENCIES_1) +NetworkManager_DEPENDENCIES = libNetworkManager.la NetworkManager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(NetworkManager_LDFLAGS) $(LDFLAGS) -o \ $@ +am_nm_iface_helper_OBJECTS = nm-dhcp-systemd.$(OBJEXT) \ + nm-iface-helper.$(OBJEXT) main-utils.$(OBJEXT) +nm_iface_helper_OBJECTS = $(am_nm_iface_helper_OBJECTS) +nm_iface_helper_DEPENDENCIES = \ + $(top_builddir)/libnm-core/libnm-core.la libsystemd-dhcp.la \ + libnm-iface-helper.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +nm_iface_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(nm_iface_helper_LDFLAGS) $(LDFLAGS) \ + -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -348,9 +408,13 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libNetworkManager_la_SOURCES) $(NetworkManager_SOURCES) +SOURCES = $(libNetworkManager_la_SOURCES) \ + $(libnm_iface_helper_la_SOURCES) $(libsystemd_dhcp_la_SOURCES) \ + $(NetworkManager_SOURCES) $(nm_iface_helper_SOURCES) DIST_SOURCES = $(am__libNetworkManager_la_SOURCES_DIST) \ - $(NetworkManager_SOURCES) + $(am__libnm_iface_helper_la_SOURCES_DIST) \ + $(libsystemd_dhcp_la_SOURCES) $(NetworkManager_SOURCES) \ + $(nm_iface_helper_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -419,11 +483,10 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = . devices/adsl devices/wwan devices/bluetooth \ - devices/wifi dhcp-manager ppp-manager settings/plugins \ - devices/wimax config/tests dhcp-manager/tests \ - dnsmasq-manager/tests platform rdisc settings/tests \ - supplicant-manager/tests tests +DIST_SUBDIRS = . devices/adsl devices/wifi dhcp-manager ppp-manager \ + settings/plugins devices/wwan devices/bluetooth devices/wimax \ + devices/team dhcp-manager/tests dnsmasq-manager/tests platform \ + rdisc supplicant-manager/tests tests DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -459,6 +522,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -582,6 +647,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -601,6 +667,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -627,7 +694,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -706,22 +773,22 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -SUBDIRS = . devices/adsl devices/wwan devices/bluetooth devices/wifi \ - dhcp-manager ppp-manager settings/plugins $(am__append_1) \ - $(am__append_2) +SUBDIRS = . devices/adsl devices/wifi dhcp-manager ppp-manager \ + settings/plugins $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) # add each subdirectory that contains a libNM source file. $(sort) is being used # primarily for its side effect of removing duplicates. -AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I${top_srcdir}/libgsystem -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util -I$(top_srcdir)/callouts \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core -I$(top_srcdir)/callouts \ + -DPREFIX=\"$(prefix)\" -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(foreach \ d,$(sort $(dir \ $(libNetworkManager_la_SOURCES))),-I$(top_srcdir)/src/$d) \ - $(am__append_10) $(DBUS_CFLAGS) $(GLIB_CFLAGS) $(GUDEV_CFLAGS) \ + $(am__append_12) $(DBUS_CFLAGS) $(GLIB_CFLAGS) $(GUDEV_CFLAGS) \ $(LIBNL_CFLAGS) $(LIBNDP_CFLAGS) $(LIBSOUP_CFLAGS) \ - $(POLKIT_CFLAGS) $(SYSTEMD_LOGIN_CFLAGS) \ + $(SYSTEMD_LOGIN_CFLAGS) $(SYSTEMD_DHCP_CFLAGS) \ -DBINDIR=\"$(bindir)\" -DDATADIR=\"$(datadir)\" \ -DLIBEXECDIR=\"$(libexecdir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" -DSBINDIR=\"$(sbindir)\" \ @@ -733,47 +800,144 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include \ -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" \ -DPPPD_PLUGIN_DIR=\"$(PPPD_PLUGIN_DIR)\" $(NULL) \ - $(am__append_11) $(am__append_12) + $(am__append_13) +noinst_LTLIBRARIES = \ + libNetworkManager.la \ + libnm-iface-helper.la \ + libsystemd-dhcp.la + + +###################### +# libsystemd-dhcp +###################### +SYSTEMD_DHCP_CFLAGS = \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/systemd \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/libsystemd-network \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp/src/shared \ + -I$(top_srcdir)/src/dhcp-manager/systemd-dhcp + +libsystemd_dhcp_la_SOURCES = \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h \ + dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c \ + dhcp-manager/systemd-dhcp/src/shared/async.h \ + dhcp-manager/systemd-dhcp/src/shared/time-util.h \ + dhcp-manager/systemd-dhcp/src/shared/siphash24.h \ + dhcp-manager/systemd-dhcp/src/shared/time-util.c \ + dhcp-manager/systemd-dhcp/src/shared/socket-util.h \ + dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h \ + dhcp-manager/systemd-dhcp/src/shared/macro.h \ + dhcp-manager/systemd-dhcp/src/shared/refcnt.h \ + dhcp-manager/systemd-dhcp/src/shared/util.c \ + dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c \ + dhcp-manager/systemd-dhcp/src/shared/siphash24.c \ + dhcp-manager/systemd-dhcp/src/shared/util.h \ + dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h \ + dhcp-manager/systemd-dhcp/src/shared/list.h \ + dhcp-manager/systemd-dhcp/src/shared/fileio.h \ + dhcp-manager/systemd-dhcp/src/shared/fileio.c \ + dhcp-manager/systemd-dhcp/src/shared/strv.h \ + dhcp-manager/systemd-dhcp/src/shared/strv.c \ + dhcp-manager/systemd-dhcp/src/shared/unaligned.h \ + dhcp-manager/systemd-dhcp/src/shared/utf8.h \ + dhcp-manager/systemd-dhcp/src/shared/utf8.c \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h \ + dhcp-manager/systemd-dhcp/src/systemd/sd-event.h \ + dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h \ + dhcp-manager/systemd-dhcp/nm-sd-adapt.h \ + dhcp-manager/systemd-dhcp/nm-sd-adapt.c + +libsystemd_dhcp_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + $(SYSTEMD_DHCP_CFLAGS) \ + $(GLIB_CFLAGS) + +libsystemd_dhcp_la_LIBADD = \ + $(GLIB_LIBS) + NetworkManager_SOURCES = \ + $(nm_device_sources) $(nm_device_headers) \ + $(nm_dhcp_client_sources) $(nm_dhcp_client_headers) \ + main-utils.c \ + main-utils.h \ main.c -NetworkManager_LDADD = libNetworkManager.la $(top_builddir)/libgsystem.la $(LIBNDP_LIBS) -noinst_LTLIBRARIES = libNetworkManager.la -nm_sources = config/nm-config.c config/nm-config.h \ - config/nm-config-device.c config/nm-config-device.h \ - devices/nm-device.c devices/nm-device.h \ - devices/nm-device-bond.c devices/nm-device-bond.h \ - devices/nm-device-bridge.c devices/nm-device-bridge.h \ - devices/nm-device-ethernet.c devices/nm-device-ethernet.h \ - devices/nm-device-factory.c devices/nm-device-factory.h \ - devices/nm-device-generic.c devices/nm-device-generic.h \ - devices/nm-device-gre.c devices/nm-device-gre.h \ - devices/nm-device-infiniband.c devices/nm-device-infiniband.h \ - devices/nm-device-macvlan.c devices/nm-device-macvlan.h \ - devices/nm-device-private.h devices/nm-device-team.c \ - devices/nm-device-team.h devices/nm-device-tun.c \ - devices/nm-device-tun.h devices/nm-device-veth.c \ - devices/nm-device-veth.h devices/nm-device-vlan.c \ - devices/nm-device-vlan.h devices/nm-device-vxlan.c \ - devices/nm-device-vxlan.h dhcp-manager/nm-dhcp-client.c \ - dhcp-manager/nm-dhcp-client.h dhcp-manager/nm-dhcp-dhclient.c \ - dhcp-manager/nm-dhcp-dhclient.h \ +NetworkManager_LDADD = libNetworkManager.la +nm_device_sources = \ + devices/nm-device-bond.c \ + devices/nm-device-bridge.c \ + devices/nm-device-ethernet.c \ + devices/nm-device-gre.c \ + devices/nm-device-infiniband.c \ + devices/nm-device-macvlan.c \ + devices/nm-device-tun.c \ + devices/nm-device-veth.c \ + devices/nm-device-vlan.c \ + devices/nm-device-vxlan.c \ + $(NULL) + +nm_device_headers = \ + devices/nm-device-bond.h \ + devices/nm-device-bridge.h \ + devices/nm-device-ethernet.h \ + devices/nm-device-gre.h \ + devices/nm-device-infiniband.h \ + devices/nm-device-macvlan.h \ + devices/nm-device-tun.h \ + devices/nm-device-veth.h \ + devices/nm-device-vlan.h \ + devices/nm-device-vxlan.h + +nm_dhcp_client_sources = \ + dhcp-manager/nm-dhcp-dhclient.c \ dhcp-manager/nm-dhcp-dhclient-utils.c \ + dhcp-manager/nm-dhcp-dhcpcd.c \ + dhcp-manager/nm-dhcp-systemd.c + +nm_dhcp_client_headers = \ + dhcp-manager/nm-dhcp-dhclient.h \ dhcp-manager/nm-dhcp-dhclient-utils.h \ - dhcp-manager/nm-dhcp-dhcpcd.c dhcp-manager/nm-dhcp-dhcpcd.h \ - dhcp-manager/nm-dhcp-manager.c dhcp-manager/nm-dhcp-manager.h \ - dns-manager/nm-dns-dnsmasq.c dns-manager/nm-dns-dnsmasq.h \ - dns-manager/nm-dns-unbound.c dns-manager/nm-dns-unbound.h \ - dns-manager/nm-dns-manager.c dns-manager/nm-dns-manager.h \ - dns-manager/nm-dns-plugin.c dns-manager/nm-dns-plugin.h \ - dns-manager/nm-dns-utils.c dns-manager/nm-dns-utils.h \ + dhcp-manager/nm-dhcp-dhcpcd.h \ + dhcp-manager/nm-dhcp-systemd.h + +nm_sources = $(nm_device_headers) $(nm_dhcp_client_headers) \ + devices/nm-device.c devices/nm-device.h \ + devices/nm-device-ethernet-utils.c \ + devices/nm-device-ethernet-utils.h devices/nm-device-factory.c \ + devices/nm-device-factory.h devices/nm-device-generic.c \ + devices/nm-device-generic.h devices/nm-device-logging.h \ + devices/nm-device-private.h dhcp-manager/nm-dhcp-client.c \ + dhcp-manager/nm-dhcp-client.h dhcp-manager/nm-dhcp-utils.c \ + dhcp-manager/nm-dhcp-utils.h dhcp-manager/nm-dhcp-listener.c \ + dhcp-manager/nm-dhcp-listener.h dhcp-manager/nm-dhcp-manager.c \ + dhcp-manager/nm-dhcp-manager.h dns-manager/nm-dns-dnsmasq.c \ + dns-manager/nm-dns-dnsmasq.h dns-manager/nm-dns-unbound.c \ + dns-manager/nm-dns-unbound.h dns-manager/nm-dns-manager.c \ + dns-manager/nm-dns-manager.h dns-manager/nm-dns-plugin.c \ + dns-manager/nm-dns-plugin.h dns-manager/nm-dns-utils.c \ + dns-manager/nm-dns-utils.h \ dnsmasq-manager/nm-dnsmasq-manager.c \ dnsmasq-manager/nm-dnsmasq-manager.h \ dnsmasq-manager/nm-dnsmasq-utils.c \ - dnsmasq-manager/nm-dnsmasq-utils.h \ - firewall-manager/nm-firewall-manager.c \ - firewall-manager/nm-firewall-manager.h logging/nm-logging.c \ - logging/nm-logging.h platform/nm-fake-platform.c \ + dnsmasq-manager/nm-dnsmasq-utils.h platform/nm-fake-platform.c \ platform/nm-fake-platform.h platform/nm-linux-platform.c \ platform/nm-linux-platform.h platform/nm-platform.c \ platform/nm-platform.h platform/wifi/wifi-utils-nl80211.c \ @@ -782,20 +946,15 @@ nm_sources = config/nm-config.c config/nm-config.h \ platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ - posix-signals/nm-posix-signals.c \ - posix-signals/nm-posix-signals.h ppp-manager/nm-ppp-manager.c \ - ppp-manager/nm-ppp-manager.h ppp-manager/nm-ppp-status.h \ - settings/nm-agent-manager.c settings/nm-agent-manager.h \ - settings/nm-inotify-helper.c settings/nm-inotify-helper.h \ - settings/nm-secret-agent.c settings/nm-secret-agent.h \ - settings/nm-settings-connection.c \ - settings/nm-settings-connection.h settings/nm-settings-error.c \ - settings/nm-settings-error.h settings/nm-settings-utils.c \ - settings/nm-settings-utils.h settings/nm-settings.c \ + ppp-manager/nm-ppp-manager.c ppp-manager/nm-ppp-manager.h \ + ppp-manager/nm-ppp-status.h settings/nm-agent-manager.c \ + settings/nm-agent-manager.h settings/nm-inotify-helper.c \ + settings/nm-inotify-helper.h settings/nm-secret-agent.c \ + settings/nm-secret-agent.h settings/nm-settings-connection.c \ + settings/nm-settings-connection.h settings/nm-settings.c \ settings/nm-settings.h settings/nm-system-config-interface.c \ settings/nm-system-config-interface.h \ settings/plugins/keyfile/common.h \ - settings/plugins/keyfile/errors.c \ settings/plugins/keyfile/nm-keyfile-connection.c \ settings/plugins/keyfile/nm-keyfile-connection.h \ settings/plugins/keyfile/plugin.c \ @@ -822,26 +981,29 @@ nm_sources = config/nm-config.c config/nm-config.h \ vpn-manager/nm-vpn-manager.h vpn-manager/nm-vpn-service.c \ vpn-manager/nm-vpn-service.h nm-activation-request.c \ nm-activation-request.h nm-active-connection.c \ - nm-active-connection.h nm-connection-provider.c \ - nm-connection-provider.h nm-connectivity.c nm-connectivity.h \ - nm-dbus-manager.c nm-dbus-manager.h nm-dcb.c nm-dcb.h \ - nm-dhcp4-config.c nm-dhcp4-config.h nm-dhcp6-config.c \ - nm-dhcp6-config.h nm-dispatcher.c nm-dispatcher.h \ - nm-enum-types.c nm-enum-types.h nm-ip4-config.c \ - nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h \ - nm-manager-auth.c nm-manager-auth.h nm-auth-subject.c \ - nm-auth-subject.h nm-manager.c nm-manager.h nm-policy.c \ - nm-policy.h nm-properties-changed-signal.c \ - nm-properties-changed-signal.h nm-rfkill-manager.c \ - nm-rfkill-manager.h nm-session-monitor.h nm-session-utils.c \ - nm-session-utils.h nm-sleep-monitor.h nm-types.h \ - NetworkManagerUtils.c NetworkManagerUtils.h $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) + nm-active-connection.h nm-config.c nm-config.h \ + nm-connection-provider.c nm-connection-provider.h \ + nm-connectivity.c nm-connectivity.h nm-dbus-manager.c \ + nm-dbus-manager.h nm-dcb.c nm-dcb.h nm-default-route-manager.c \ + nm-default-route-manager.h nm-dhcp4-config.c nm-dhcp4-config.h \ + nm-dhcp6-config.c nm-dhcp6-config.h nm-dispatcher.c \ + nm-dispatcher.h nm-enum-types.c nm-enum-types.h \ + nm-firewall-manager.c nm-firewall-manager.h nm-ip4-config.c \ + nm-ip4-config.h nm-ip6-config.c nm-ip6-config.h nm-logging.c \ + nm-logging.h nm-auth-manager.c nm-auth-manager.h \ + nm-auth-subject.c nm-auth-subject.h nm-auth-utils.c \ + nm-auth-utils.h nm-manager.c nm-manager.h nm-policy.c \ + nm-policy.h nm-posix-signals.c nm-posix-signals.h \ + nm-properties-changed-signal.c nm-properties-changed-signal.h \ + nm-rfkill-manager.c nm-rfkill-manager.h nm-session-monitor.h \ + nm-session-utils.c nm-session-utils.h nm-sleep-monitor.h \ + nm-types.h NetworkManagerUtils.c NetworkManagerUtils.h \ + $(am__append_5) $(am__append_6) $(am__append_7) \ + $(am__append_8) $(am__append_9) $(am__append_10) GLIB_GENERATED = nm-enum-types.h nm-enum-types.c -GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM --fhead '\#include \n' GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_enum_types_sources = $(nm_sources) $(am__append_9) +nm_enum_types_sources = $(nm_sources) $(am__append_11) BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) glue_sources = \ nm-access-point-glue.h \ @@ -855,7 +1017,6 @@ glue_sources = \ nm-device-gre-glue.h \ nm-device-infiniband-glue.h \ nm-device-macvlan-glue.h \ - nm-device-team-glue.h \ nm-device-tun-glue.h \ nm-device-veth-glue.h \ nm-device-vlan-glue.h \ @@ -874,12 +1035,61 @@ libNetworkManager_la_SOURCES = \ $(nm_sources) \ $(glue_sources) -libNetworkManager_la_LIBADD = $(top_builddir)/libgsystem.la \ - $(top_builddir)/libnm-util/libnm-util.la $(DBUS_LIBS) \ - $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(POLKIT_LIBS) \ - $(SYSTEMD_LOGIN_LIBS) $(LIBDL) $(LIBM) $(am__append_13) \ +libNetworkManager_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la libsystemd-dhcp.la \ + $(DBUS_LIBS) $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) \ + $(SYSTEMD_LOGIN_LIBS) $(LIBNDP_LIBS) $(LIBDL) $(LIBM) \ $(am__append_14) NetworkManager_LDFLAGS = -rdynamic + +###################### +libnm_iface_helper_la_SOURCES = dhcp-manager/nm-dhcp-client.c \ + dhcp-manager/nm-dhcp-client.h dhcp-manager/nm-dhcp-utils.c \ + dhcp-manager/nm-dhcp-utils.h dhcp-manager/nm-dhcp-manager.c \ + dhcp-manager/nm-dhcp-manager.h platform/nm-linux-platform.c \ + platform/nm-linux-platform.h platform/nm-platform.c \ + platform/nm-platform.h platform/wifi/wifi-utils-nl80211.c \ + platform/wifi/wifi-utils-nl80211.h \ + platform/wifi/wifi-utils-private.h platform/wifi/wifi-utils.c \ + platform/wifi/wifi-utils.h rdisc/nm-fake-rdisc.c \ + rdisc/nm-fake-rdisc.h rdisc/nm-lndp-rdisc.c \ + rdisc/nm-lndp-rdisc.h rdisc/nm-rdisc.c rdisc/nm-rdisc.h \ + nm-ip4-config.c nm-ip4-config.h nm-ip6-config.c \ + nm-ip6-config.h nm-enum-types.c nm-enum-types.h nm-logging.c \ + nm-logging.h nm-posix-signals.c nm-posix-signals.h \ + NetworkManagerUtils.c NetworkManagerUtils.h $(am__append_15) +libnm_iface_helper_la_LIBADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + libsystemd-dhcp.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GUDEV_LIBS) \ + $(LIBNL_LIBS) \ + $(LIBNDP_LIBS) \ + $(LIBDL) \ + $(LIBM) + +nm_iface_helper_SOURCES = \ + dhcp-manager/nm-dhcp-systemd.h \ + dhcp-manager/nm-dhcp-systemd.c \ + nm-iface-helper.c \ + main-utils.c \ + main-utils.h + +nm_iface_helper_LDADD = \ + $(top_builddir)/libnm-core/libnm-core.la \ + libsystemd-dhcp.la \ + libnm-iface-helper.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GUDEV_LIBS) \ + $(LIBNL_LIBS) \ + $(LIBNDP_LIBS) \ + $(LIBM) + +nm_iface_helper_LDFLAGS = -rdynamic + +###################### dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = org.freedesktop.NetworkManager.conf EXTRA_DIST = \ @@ -943,6 +1153,61 @@ clean-noinstLTLIBRARIES: libNetworkManager.la: $(libNetworkManager_la_OBJECTS) $(libNetworkManager_la_DEPENDENCIES) $(EXTRA_libNetworkManager_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libNetworkManager_la_OBJECTS) $(libNetworkManager_la_LIBADD) $(LIBS) + +libnm-iface-helper.la: $(libnm_iface_helper_la_OBJECTS) $(libnm_iface_helper_la_DEPENDENCIES) $(EXTRA_libnm_iface_helper_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libnm_iface_helper_la_OBJECTS) $(libnm_iface_helper_la_LIBADD) $(LIBS) + +libsystemd-dhcp.la: $(libsystemd_dhcp_la_OBJECTS) $(libsystemd_dhcp_la_DEPENDENCIES) $(EXTRA_libsystemd_dhcp_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libsystemd_dhcp_la_OBJECTS) $(libsystemd_dhcp_la_LIBADD) $(LIBS) +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ @@ -997,6 +1262,10 @@ NetworkManager$(EXEEXT): $(NetworkManager_OBJECTS) $(NetworkManager_DEPENDENCIES @rm -f NetworkManager$(EXEEXT) $(AM_V_CCLD)$(NetworkManager_LINK) $(NetworkManager_OBJECTS) $(NetworkManager_LDADD) $(LIBS) +nm-iface-helper$(EXEEXT): $(nm_iface_helper_OBJECTS) $(nm_iface_helper_DEPENDENCIES) $(EXTRA_nm_iface_helper_DEPENDENCIES) + @rm -f nm-iface-helper$(EXEEXT) + $(AM_V_CCLD)$(nm_iface_helper_LINK) $(nm_iface_helper_OBJECTS) $(nm_iface_helper_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -1004,38 +1273,61 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManagerUtils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-dhcp-network.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-dhcp-option.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-dhcp-packet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-dhcp6-network.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-dhcp6-option.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-fileio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-in-addr-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-network-internal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-nm-sd-adapt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-lease.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-client.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-lease.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-siphash24.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-strv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-time-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-utf8.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystemd_dhcp_la-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-activation-request.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-active-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-agent-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-auth-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-auth-subject.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-auth-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-call-store.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-config-device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connection-provider.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-connectivity.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dbus-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dcb.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bond.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bridge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ethernet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-default-route-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bond.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bridge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ethernet-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-ethernet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-factory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-generic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-gre.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-infiniband.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-macvlan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-team.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-tun.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-veth.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vlan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vxlan.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-gre.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-infiniband.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-macvlan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-tun.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-veth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vlan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-vxlan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-client.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient-utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhcpcd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhcpcd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-listener.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-systemd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp6-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dispatcher.Plo@am__quote@ @@ -1050,6 +1342,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-fake-platform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-fake-rdisc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-firewall-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-iface-helper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-inotify-helper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ip4-config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ip6-config.Plo@am__quote@ @@ -1057,7 +1350,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-linux-platform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-lndp-rdisc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-logging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-manager-auth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-platform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-policy.Plo@am__quote@ @@ -1072,8 +1364,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-session-monitor-systemd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-session-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-settings-connection.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-settings-error.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-settings-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-settings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-sleep-monitor-systemd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-sleep-monitor-upower.Plo@am__quote@ @@ -1114,20 +1404,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -nm-config.lo: config/nm-config.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-config.lo -MD -MP -MF $(DEPDIR)/nm-config.Tpo -c -o nm-config.lo `test -f 'config/nm-config.c' || echo '$(srcdir)/'`config/nm-config.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-config.Tpo $(DEPDIR)/nm-config.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config/nm-config.c' object='nm-config.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-config.lo `test -f 'config/nm-config.c' || echo '$(srcdir)/'`config/nm-config.c - -nm-config-device.lo: config/nm-config-device.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-config-device.lo -MD -MP -MF $(DEPDIR)/nm-config-device.Tpo -c -o nm-config-device.lo `test -f 'config/nm-config-device.c' || echo '$(srcdir)/'`config/nm-config-device.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-config-device.Tpo $(DEPDIR)/nm-config-device.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config/nm-config-device.c' object='nm-config-device.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-config-device.lo `test -f 'config/nm-config-device.c' || echo '$(srcdir)/'`config/nm-config-device.c - nm-device.lo: devices/nm-device.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device.lo -MD -MP -MF $(DEPDIR)/nm-device.Tpo -c -o nm-device.lo `test -f 'devices/nm-device.c' || echo '$(srcdir)/'`devices/nm-device.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device.Tpo $(DEPDIR)/nm-device.Plo @@ -1135,26 +1411,12 @@ nm-device.lo: devices/nm-device.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device.lo `test -f 'devices/nm-device.c' || echo '$(srcdir)/'`devices/nm-device.c -nm-device-bond.lo: devices/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bond.lo -MD -MP -MF $(DEPDIR)/nm-device-bond.Tpo -c -o nm-device-bond.lo `test -f 'devices/nm-device-bond.c' || echo '$(srcdir)/'`devices/nm-device-bond.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bond.Tpo $(DEPDIR)/nm-device-bond.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bond.c' object='nm-device-bond.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bond.lo `test -f 'devices/nm-device-bond.c' || echo '$(srcdir)/'`devices/nm-device-bond.c - -nm-device-bridge.lo: devices/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bridge.lo -MD -MP -MF $(DEPDIR)/nm-device-bridge.Tpo -c -o nm-device-bridge.lo `test -f 'devices/nm-device-bridge.c' || echo '$(srcdir)/'`devices/nm-device-bridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bridge.Tpo $(DEPDIR)/nm-device-bridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bridge.c' object='nm-device-bridge.lo' libtool=yes @AMDEPBACKSLASH@ +nm-device-ethernet-utils.lo: devices/nm-device-ethernet-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-ethernet-utils.lo -MD -MP -MF $(DEPDIR)/nm-device-ethernet-utils.Tpo -c -o nm-device-ethernet-utils.lo `test -f 'devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`devices/nm-device-ethernet-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-ethernet-utils.Tpo $(DEPDIR)/nm-device-ethernet-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-ethernet-utils.c' object='nm-device-ethernet-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bridge.lo `test -f 'devices/nm-device-bridge.c' || echo '$(srcdir)/'`devices/nm-device-bridge.c - -nm-device-ethernet.lo: devices/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-ethernet.lo -MD -MP -MF $(DEPDIR)/nm-device-ethernet.Tpo -c -o nm-device-ethernet.lo `test -f 'devices/nm-device-ethernet.c' || echo '$(srcdir)/'`devices/nm-device-ethernet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-ethernet.Tpo $(DEPDIR)/nm-device-ethernet.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-ethernet.c' object='nm-device-ethernet.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-ethernet.lo `test -f 'devices/nm-device-ethernet.c' || echo '$(srcdir)/'`devices/nm-device-ethernet.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-ethernet-utils.lo `test -f 'devices/nm-device-ethernet-utils.c' || echo '$(srcdir)/'`devices/nm-device-ethernet-utils.c nm-device-factory.lo: devices/nm-device-factory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-factory.lo -MD -MP -MF $(DEPDIR)/nm-device-factory.Tpo -c -o nm-device-factory.lo `test -f 'devices/nm-device-factory.c' || echo '$(srcdir)/'`devices/nm-device-factory.c @@ -1170,62 +1432,6 @@ nm-device-generic.lo: devices/nm-device-generic.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-generic.lo `test -f 'devices/nm-device-generic.c' || echo '$(srcdir)/'`devices/nm-device-generic.c -nm-device-gre.lo: devices/nm-device-gre.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-gre.lo -MD -MP -MF $(DEPDIR)/nm-device-gre.Tpo -c -o nm-device-gre.lo `test -f 'devices/nm-device-gre.c' || echo '$(srcdir)/'`devices/nm-device-gre.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-gre.Tpo $(DEPDIR)/nm-device-gre.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-gre.c' object='nm-device-gre.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-gre.lo `test -f 'devices/nm-device-gre.c' || echo '$(srcdir)/'`devices/nm-device-gre.c - -nm-device-infiniband.lo: devices/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-infiniband.lo -MD -MP -MF $(DEPDIR)/nm-device-infiniband.Tpo -c -o nm-device-infiniband.lo `test -f 'devices/nm-device-infiniband.c' || echo '$(srcdir)/'`devices/nm-device-infiniband.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-infiniband.Tpo $(DEPDIR)/nm-device-infiniband.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-infiniband.c' object='nm-device-infiniband.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-infiniband.lo `test -f 'devices/nm-device-infiniband.c' || echo '$(srcdir)/'`devices/nm-device-infiniband.c - -nm-device-macvlan.lo: devices/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-macvlan.lo -MD -MP -MF $(DEPDIR)/nm-device-macvlan.Tpo -c -o nm-device-macvlan.lo `test -f 'devices/nm-device-macvlan.c' || echo '$(srcdir)/'`devices/nm-device-macvlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-macvlan.Tpo $(DEPDIR)/nm-device-macvlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-macvlan.c' object='nm-device-macvlan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-macvlan.lo `test -f 'devices/nm-device-macvlan.c' || echo '$(srcdir)/'`devices/nm-device-macvlan.c - -nm-device-team.lo: devices/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-team.lo -MD -MP -MF $(DEPDIR)/nm-device-team.Tpo -c -o nm-device-team.lo `test -f 'devices/nm-device-team.c' || echo '$(srcdir)/'`devices/nm-device-team.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-team.Tpo $(DEPDIR)/nm-device-team.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-team.c' object='nm-device-team.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-team.lo `test -f 'devices/nm-device-team.c' || echo '$(srcdir)/'`devices/nm-device-team.c - -nm-device-tun.lo: devices/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-tun.lo -MD -MP -MF $(DEPDIR)/nm-device-tun.Tpo -c -o nm-device-tun.lo `test -f 'devices/nm-device-tun.c' || echo '$(srcdir)/'`devices/nm-device-tun.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-tun.Tpo $(DEPDIR)/nm-device-tun.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-tun.c' object='nm-device-tun.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-tun.lo `test -f 'devices/nm-device-tun.c' || echo '$(srcdir)/'`devices/nm-device-tun.c - -nm-device-veth.lo: devices/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-veth.lo -MD -MP -MF $(DEPDIR)/nm-device-veth.Tpo -c -o nm-device-veth.lo `test -f 'devices/nm-device-veth.c' || echo '$(srcdir)/'`devices/nm-device-veth.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-veth.Tpo $(DEPDIR)/nm-device-veth.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-veth.c' object='nm-device-veth.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-veth.lo `test -f 'devices/nm-device-veth.c' || echo '$(srcdir)/'`devices/nm-device-veth.c - -nm-device-vlan.lo: devices/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vlan.lo -MD -MP -MF $(DEPDIR)/nm-device-vlan.Tpo -c -o nm-device-vlan.lo `test -f 'devices/nm-device-vlan.c' || echo '$(srcdir)/'`devices/nm-device-vlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vlan.Tpo $(DEPDIR)/nm-device-vlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vlan.c' object='nm-device-vlan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vlan.lo `test -f 'devices/nm-device-vlan.c' || echo '$(srcdir)/'`devices/nm-device-vlan.c - -nm-device-vxlan.lo: devices/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vxlan.lo -MD -MP -MF $(DEPDIR)/nm-device-vxlan.Tpo -c -o nm-device-vxlan.lo `test -f 'devices/nm-device-vxlan.c' || echo '$(srcdir)/'`devices/nm-device-vxlan.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vxlan.Tpo $(DEPDIR)/nm-device-vxlan.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vxlan.c' object='nm-device-vxlan.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vxlan.lo `test -f 'devices/nm-device-vxlan.c' || echo '$(srcdir)/'`devices/nm-device-vxlan.c - nm-dhcp-client.lo: dhcp-manager/nm-dhcp-client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-client.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-client.Tpo -c -o nm-dhcp-client.lo `test -f 'dhcp-manager/nm-dhcp-client.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-client.Tpo $(DEPDIR)/nm-dhcp-client.Plo @@ -1233,26 +1439,19 @@ nm-dhcp-client.lo: dhcp-manager/nm-dhcp-client.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-client.lo `test -f 'dhcp-manager/nm-dhcp-client.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-client.c -nm-dhcp-dhclient.lo: dhcp-manager/nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient.Tpo -c -o nm-dhcp-dhclient.lo `test -f 'dhcp-manager/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient.Tpo $(DEPDIR)/nm-dhcp-dhclient.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient.c' object='nm-dhcp-dhclient.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient.lo `test -f 'dhcp-manager/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient.c - -nm-dhcp-dhclient-utils.lo: dhcp-manager/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.lo `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.lo' libtool=yes @AMDEPBACKSLASH@ +nm-dhcp-utils.lo: dhcp-manager/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-utils.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-utils.Tpo -c -o nm-dhcp-utils.lo `test -f 'dhcp-manager/nm-dhcp-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-utils.Tpo $(DEPDIR)/nm-dhcp-utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-utils.c' object='nm-dhcp-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.lo `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-utils.lo `test -f 'dhcp-manager/nm-dhcp-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-utils.c -nm-dhcp-dhcpcd.lo: dhcp-manager/nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhcpcd.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-dhcpcd.Tpo -c -o nm-dhcp-dhcpcd.lo `test -f 'dhcp-manager/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhcpcd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhcpcd.Tpo $(DEPDIR)/nm-dhcp-dhcpcd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhcpcd.c' object='nm-dhcp-dhcpcd.lo' libtool=yes @AMDEPBACKSLASH@ +nm-dhcp-listener.lo: dhcp-manager/nm-dhcp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-listener.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-listener.Tpo -c -o nm-dhcp-listener.lo `test -f 'dhcp-manager/nm-dhcp-listener.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-listener.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-listener.Tpo $(DEPDIR)/nm-dhcp-listener.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-listener.c' object='nm-dhcp-listener.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhcpcd.lo `test -f 'dhcp-manager/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhcpcd.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-listener.lo `test -f 'dhcp-manager/nm-dhcp-listener.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-listener.c nm-dhcp-manager.lo: dhcp-manager/nm-dhcp-manager.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-manager.lo -MD -MP -MF $(DEPDIR)/nm-dhcp-manager.Tpo -c -o nm-dhcp-manager.lo `test -f 'dhcp-manager/nm-dhcp-manager.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-manager.c @@ -1310,20 +1509,6 @@ nm-dnsmasq-utils.lo: dnsmasq-manager/nm-dnsmasq-utils.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dnsmasq-utils.lo `test -f 'dnsmasq-manager/nm-dnsmasq-utils.c' || echo '$(srcdir)/'`dnsmasq-manager/nm-dnsmasq-utils.c -nm-firewall-manager.lo: firewall-manager/nm-firewall-manager.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-firewall-manager.lo -MD -MP -MF $(DEPDIR)/nm-firewall-manager.Tpo -c -o nm-firewall-manager.lo `test -f 'firewall-manager/nm-firewall-manager.c' || echo '$(srcdir)/'`firewall-manager/nm-firewall-manager.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-firewall-manager.Tpo $(DEPDIR)/nm-firewall-manager.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='firewall-manager/nm-firewall-manager.c' object='nm-firewall-manager.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-firewall-manager.lo `test -f 'firewall-manager/nm-firewall-manager.c' || echo '$(srcdir)/'`firewall-manager/nm-firewall-manager.c - -nm-logging.lo: logging/nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-logging.lo -MD -MP -MF $(DEPDIR)/nm-logging.Tpo -c -o nm-logging.lo `test -f 'logging/nm-logging.c' || echo '$(srcdir)/'`logging/nm-logging.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-logging.Tpo $(DEPDIR)/nm-logging.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logging/nm-logging.c' object='nm-logging.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-logging.lo `test -f 'logging/nm-logging.c' || echo '$(srcdir)/'`logging/nm-logging.c - nm-fake-platform.lo: platform/nm-fake-platform.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-fake-platform.lo -MD -MP -MF $(DEPDIR)/nm-fake-platform.Tpo -c -o nm-fake-platform.lo `test -f 'platform/nm-fake-platform.c' || echo '$(srcdir)/'`platform/nm-fake-platform.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-fake-platform.Tpo $(DEPDIR)/nm-fake-platform.Plo @@ -1380,13 +1565,6 @@ nm-rdisc.lo: rdisc/nm-rdisc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-rdisc.lo `test -f 'rdisc/nm-rdisc.c' || echo '$(srcdir)/'`rdisc/nm-rdisc.c -nm-posix-signals.lo: posix-signals/nm-posix-signals.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-posix-signals.lo -MD -MP -MF $(DEPDIR)/nm-posix-signals.Tpo -c -o nm-posix-signals.lo `test -f 'posix-signals/nm-posix-signals.c' || echo '$(srcdir)/'`posix-signals/nm-posix-signals.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-posix-signals.Tpo $(DEPDIR)/nm-posix-signals.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='posix-signals/nm-posix-signals.c' object='nm-posix-signals.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-posix-signals.lo `test -f 'posix-signals/nm-posix-signals.c' || echo '$(srcdir)/'`posix-signals/nm-posix-signals.c - nm-ppp-manager.lo: ppp-manager/nm-ppp-manager.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-ppp-manager.lo -MD -MP -MF $(DEPDIR)/nm-ppp-manager.Tpo -c -o nm-ppp-manager.lo `test -f 'ppp-manager/nm-ppp-manager.c' || echo '$(srcdir)/'`ppp-manager/nm-ppp-manager.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-ppp-manager.Tpo $(DEPDIR)/nm-ppp-manager.Plo @@ -1422,20 +1600,6 @@ nm-settings-connection.lo: settings/nm-settings-connection.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-settings-connection.lo `test -f 'settings/nm-settings-connection.c' || echo '$(srcdir)/'`settings/nm-settings-connection.c -nm-settings-error.lo: settings/nm-settings-error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-settings-error.lo -MD -MP -MF $(DEPDIR)/nm-settings-error.Tpo -c -o nm-settings-error.lo `test -f 'settings/nm-settings-error.c' || echo '$(srcdir)/'`settings/nm-settings-error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-settings-error.Tpo $(DEPDIR)/nm-settings-error.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='settings/nm-settings-error.c' object='nm-settings-error.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-settings-error.lo `test -f 'settings/nm-settings-error.c' || echo '$(srcdir)/'`settings/nm-settings-error.c - -nm-settings-utils.lo: settings/nm-settings-utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-settings-utils.lo -MD -MP -MF $(DEPDIR)/nm-settings-utils.Tpo -c -o nm-settings-utils.lo `test -f 'settings/nm-settings-utils.c' || echo '$(srcdir)/'`settings/nm-settings-utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-settings-utils.Tpo $(DEPDIR)/nm-settings-utils.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='settings/nm-settings-utils.c' object='nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-settings-utils.lo `test -f 'settings/nm-settings-utils.c' || echo '$(srcdir)/'`settings/nm-settings-utils.c - nm-settings.lo: settings/nm-settings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-settings.lo -MD -MP -MF $(DEPDIR)/nm-settings.Tpo -c -o nm-settings.lo `test -f 'settings/nm-settings.c' || echo '$(srcdir)/'`settings/nm-settings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-settings.Tpo $(DEPDIR)/nm-settings.Plo @@ -1450,13 +1614,6 @@ nm-system-config-interface.lo: settings/nm-system-config-interface.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-system-config-interface.lo `test -f 'settings/nm-system-config-interface.c' || echo '$(srcdir)/'`settings/nm-system-config-interface.c -errors.lo: settings/plugins/keyfile/errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.lo -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.lo `test -f 'settings/plugins/keyfile/errors.c' || echo '$(srcdir)/'`settings/plugins/keyfile/errors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='settings/plugins/keyfile/errors.c' object='errors.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.lo `test -f 'settings/plugins/keyfile/errors.c' || echo '$(srcdir)/'`settings/plugins/keyfile/errors.c - nm-keyfile-connection.lo: settings/plugins/keyfile/nm-keyfile-connection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-keyfile-connection.lo -MD -MP -MF $(DEPDIR)/nm-keyfile-connection.Tpo -c -o nm-keyfile-connection.lo `test -f 'settings/plugins/keyfile/nm-keyfile-connection.c' || echo '$(srcdir)/'`settings/plugins/keyfile/nm-keyfile-connection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-keyfile-connection.Tpo $(DEPDIR)/nm-keyfile-connection.Plo @@ -1555,6 +1712,328 @@ wifi-utils-wext.lo: platform/wifi/wifi-utils-wext.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wifi-utils-wext.lo `test -f 'platform/wifi/wifi-utils-wext.c' || echo '$(srcdir)/'`platform/wifi/wifi-utils-wext.c +libsystemd_dhcp_la-dhcp-network.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-dhcp-network.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-dhcp-network.Tpo -c -o libsystemd_dhcp_la-dhcp-network.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-dhcp-network.Tpo $(DEPDIR)/libsystemd_dhcp_la-dhcp-network.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c' object='libsystemd_dhcp_la-dhcp-network.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-dhcp-network.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c + +libsystemd_dhcp_la-dhcp-packet.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-dhcp-packet.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-dhcp-packet.Tpo -c -o libsystemd_dhcp_la-dhcp-packet.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-dhcp-packet.Tpo $(DEPDIR)/libsystemd_dhcp_la-dhcp-packet.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c' object='libsystemd_dhcp_la-dhcp-packet.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-dhcp-packet.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c + +libsystemd_dhcp_la-dhcp6-network.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-dhcp6-network.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-dhcp6-network.Tpo -c -o libsystemd_dhcp_la-dhcp6-network.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-dhcp6-network.Tpo $(DEPDIR)/libsystemd_dhcp_la-dhcp6-network.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c' object='libsystemd_dhcp_la-dhcp6-network.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-dhcp6-network.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c + +libsystemd_dhcp_la-dhcp6-option.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-dhcp6-option.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-dhcp6-option.Tpo -c -o libsystemd_dhcp_la-dhcp6-option.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-dhcp6-option.Tpo $(DEPDIR)/libsystemd_dhcp_la-dhcp6-option.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c' object='libsystemd_dhcp_la-dhcp6-option.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-dhcp6-option.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c + +libsystemd_dhcp_la-network-internal.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-network-internal.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-network-internal.Tpo -c -o libsystemd_dhcp_la-network-internal.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-network-internal.Tpo $(DEPDIR)/libsystemd_dhcp_la-network-internal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c' object='libsystemd_dhcp_la-network-internal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-network-internal.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c + +libsystemd_dhcp_la-sd-dhcp-lease.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-sd-dhcp-lease.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-lease.Tpo -c -o libsystemd_dhcp_la-sd-dhcp-lease.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-lease.Tpo $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-lease.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c' object='libsystemd_dhcp_la-sd-dhcp-lease.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-sd-dhcp-lease.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c + +libsystemd_dhcp_la-sd-dhcp-client.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-sd-dhcp-client.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-client.Tpo -c -o libsystemd_dhcp_la-sd-dhcp-client.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-client.Tpo $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c' object='libsystemd_dhcp_la-sd-dhcp-client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-sd-dhcp-client.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c + +libsystemd_dhcp_la-dhcp-option.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-dhcp-option.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-dhcp-option.Tpo -c -o libsystemd_dhcp_la-dhcp-option.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-dhcp-option.Tpo $(DEPDIR)/libsystemd_dhcp_la-dhcp-option.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c' object='libsystemd_dhcp_la-dhcp-option.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-dhcp-option.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c + +libsystemd_dhcp_la-sd-dhcp6-lease.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-sd-dhcp6-lease.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-lease.Tpo -c -o libsystemd_dhcp_la-sd-dhcp6-lease.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-lease.Tpo $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-lease.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c' object='libsystemd_dhcp_la-sd-dhcp6-lease.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-sd-dhcp6-lease.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c + +libsystemd_dhcp_la-sd-dhcp6-client.lo: dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-sd-dhcp6-client.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-client.Tpo -c -o libsystemd_dhcp_la-sd-dhcp6-client.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-client.Tpo $(DEPDIR)/libsystemd_dhcp_la-sd-dhcp6-client.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c' object='libsystemd_dhcp_la-sd-dhcp6-client.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-sd-dhcp6-client.lo `test -f 'dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c + +libsystemd_dhcp_la-time-util.lo: dhcp-manager/systemd-dhcp/src/shared/time-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-time-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-time-util.Tpo -c -o libsystemd_dhcp_la-time-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/time-util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/time-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-time-util.Tpo $(DEPDIR)/libsystemd_dhcp_la-time-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/time-util.c' object='libsystemd_dhcp_la-time-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-time-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/time-util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/time-util.c + +libsystemd_dhcp_la-util.lo: dhcp-manager/systemd-dhcp/src/shared/util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-util.Tpo -c -o libsystemd_dhcp_la-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-util.Tpo $(DEPDIR)/libsystemd_dhcp_la-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/util.c' object='libsystemd_dhcp_la-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/util.c + +libsystemd_dhcp_la-in-addr-util.lo: dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-in-addr-util.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-in-addr-util.Tpo -c -o libsystemd_dhcp_la-in-addr-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-in-addr-util.Tpo $(DEPDIR)/libsystemd_dhcp_la-in-addr-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c' object='libsystemd_dhcp_la-in-addr-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-in-addr-util.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c + +libsystemd_dhcp_la-siphash24.lo: dhcp-manager/systemd-dhcp/src/shared/siphash24.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-siphash24.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-siphash24.Tpo -c -o libsystemd_dhcp_la-siphash24.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/siphash24.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/siphash24.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-siphash24.Tpo $(DEPDIR)/libsystemd_dhcp_la-siphash24.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/siphash24.c' object='libsystemd_dhcp_la-siphash24.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-siphash24.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/siphash24.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/siphash24.c + +libsystemd_dhcp_la-fileio.lo: dhcp-manager/systemd-dhcp/src/shared/fileio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-fileio.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-fileio.Tpo -c -o libsystemd_dhcp_la-fileio.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/fileio.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/fileio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-fileio.Tpo $(DEPDIR)/libsystemd_dhcp_la-fileio.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/fileio.c' object='libsystemd_dhcp_la-fileio.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-fileio.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/fileio.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/fileio.c + +libsystemd_dhcp_la-strv.lo: dhcp-manager/systemd-dhcp/src/shared/strv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-strv.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-strv.Tpo -c -o libsystemd_dhcp_la-strv.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/strv.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/strv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-strv.Tpo $(DEPDIR)/libsystemd_dhcp_la-strv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/strv.c' object='libsystemd_dhcp_la-strv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-strv.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/strv.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/strv.c + +libsystemd_dhcp_la-utf8.lo: dhcp-manager/systemd-dhcp/src/shared/utf8.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-utf8.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-utf8.Tpo -c -o libsystemd_dhcp_la-utf8.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/utf8.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/utf8.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-utf8.Tpo $(DEPDIR)/libsystemd_dhcp_la-utf8.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/src/shared/utf8.c' object='libsystemd_dhcp_la-utf8.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-utf8.lo `test -f 'dhcp-manager/systemd-dhcp/src/shared/utf8.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/src/shared/utf8.c + +libsystemd_dhcp_la-nm-sd-adapt.lo: dhcp-manager/systemd-dhcp/nm-sd-adapt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystemd_dhcp_la-nm-sd-adapt.lo -MD -MP -MF $(DEPDIR)/libsystemd_dhcp_la-nm-sd-adapt.Tpo -c -o libsystemd_dhcp_la-nm-sd-adapt.lo `test -f 'dhcp-manager/systemd-dhcp/nm-sd-adapt.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/nm-sd-adapt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystemd_dhcp_la-nm-sd-adapt.Tpo $(DEPDIR)/libsystemd_dhcp_la-nm-sd-adapt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/systemd-dhcp/nm-sd-adapt.c' object='libsystemd_dhcp_la-nm-sd-adapt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystemd_dhcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystemd_dhcp_la-nm-sd-adapt.lo `test -f 'dhcp-manager/systemd-dhcp/nm-sd-adapt.c' || echo '$(srcdir)/'`dhcp-manager/systemd-dhcp/nm-sd-adapt.c + +nm-device-bond.o: devices/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bond.o -MD -MP -MF $(DEPDIR)/nm-device-bond.Tpo -c -o nm-device-bond.o `test -f 'devices/nm-device-bond.c' || echo '$(srcdir)/'`devices/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bond.Tpo $(DEPDIR)/nm-device-bond.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bond.c' object='nm-device-bond.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bond.o `test -f 'devices/nm-device-bond.c' || echo '$(srcdir)/'`devices/nm-device-bond.c + +nm-device-bond.obj: devices/nm-device-bond.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bond.obj -MD -MP -MF $(DEPDIR)/nm-device-bond.Tpo -c -o nm-device-bond.obj `if test -f 'devices/nm-device-bond.c'; then $(CYGPATH_W) 'devices/nm-device-bond.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-bond.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bond.Tpo $(DEPDIR)/nm-device-bond.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bond.c' object='nm-device-bond.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bond.obj `if test -f 'devices/nm-device-bond.c'; then $(CYGPATH_W) 'devices/nm-device-bond.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-bond.c'; fi` + +nm-device-bridge.o: devices/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bridge.o -MD -MP -MF $(DEPDIR)/nm-device-bridge.Tpo -c -o nm-device-bridge.o `test -f 'devices/nm-device-bridge.c' || echo '$(srcdir)/'`devices/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bridge.Tpo $(DEPDIR)/nm-device-bridge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bridge.c' object='nm-device-bridge.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bridge.o `test -f 'devices/nm-device-bridge.c' || echo '$(srcdir)/'`devices/nm-device-bridge.c + +nm-device-bridge.obj: devices/nm-device-bridge.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-bridge.obj -MD -MP -MF $(DEPDIR)/nm-device-bridge.Tpo -c -o nm-device-bridge.obj `if test -f 'devices/nm-device-bridge.c'; then $(CYGPATH_W) 'devices/nm-device-bridge.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-bridge.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-bridge.Tpo $(DEPDIR)/nm-device-bridge.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-bridge.c' object='nm-device-bridge.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-bridge.obj `if test -f 'devices/nm-device-bridge.c'; then $(CYGPATH_W) 'devices/nm-device-bridge.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-bridge.c'; fi` + +nm-device-ethernet.o: devices/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-ethernet.o -MD -MP -MF $(DEPDIR)/nm-device-ethernet.Tpo -c -o nm-device-ethernet.o `test -f 'devices/nm-device-ethernet.c' || echo '$(srcdir)/'`devices/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-ethernet.Tpo $(DEPDIR)/nm-device-ethernet.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-ethernet.c' object='nm-device-ethernet.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-ethernet.o `test -f 'devices/nm-device-ethernet.c' || echo '$(srcdir)/'`devices/nm-device-ethernet.c + +nm-device-ethernet.obj: devices/nm-device-ethernet.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-ethernet.obj -MD -MP -MF $(DEPDIR)/nm-device-ethernet.Tpo -c -o nm-device-ethernet.obj `if test -f 'devices/nm-device-ethernet.c'; then $(CYGPATH_W) 'devices/nm-device-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-ethernet.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-ethernet.Tpo $(DEPDIR)/nm-device-ethernet.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-ethernet.c' object='nm-device-ethernet.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-ethernet.obj `if test -f 'devices/nm-device-ethernet.c'; then $(CYGPATH_W) 'devices/nm-device-ethernet.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-ethernet.c'; fi` + +nm-device-gre.o: devices/nm-device-gre.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-gre.o -MD -MP -MF $(DEPDIR)/nm-device-gre.Tpo -c -o nm-device-gre.o `test -f 'devices/nm-device-gre.c' || echo '$(srcdir)/'`devices/nm-device-gre.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-gre.Tpo $(DEPDIR)/nm-device-gre.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-gre.c' object='nm-device-gre.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-gre.o `test -f 'devices/nm-device-gre.c' || echo '$(srcdir)/'`devices/nm-device-gre.c + +nm-device-gre.obj: devices/nm-device-gre.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-gre.obj -MD -MP -MF $(DEPDIR)/nm-device-gre.Tpo -c -o nm-device-gre.obj `if test -f 'devices/nm-device-gre.c'; then $(CYGPATH_W) 'devices/nm-device-gre.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-gre.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-gre.Tpo $(DEPDIR)/nm-device-gre.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-gre.c' object='nm-device-gre.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-gre.obj `if test -f 'devices/nm-device-gre.c'; then $(CYGPATH_W) 'devices/nm-device-gre.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-gre.c'; fi` + +nm-device-infiniband.o: devices/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-infiniband.o -MD -MP -MF $(DEPDIR)/nm-device-infiniband.Tpo -c -o nm-device-infiniband.o `test -f 'devices/nm-device-infiniband.c' || echo '$(srcdir)/'`devices/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-infiniband.Tpo $(DEPDIR)/nm-device-infiniband.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-infiniband.c' object='nm-device-infiniband.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-infiniband.o `test -f 'devices/nm-device-infiniband.c' || echo '$(srcdir)/'`devices/nm-device-infiniband.c + +nm-device-infiniband.obj: devices/nm-device-infiniband.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-infiniband.obj -MD -MP -MF $(DEPDIR)/nm-device-infiniband.Tpo -c -o nm-device-infiniband.obj `if test -f 'devices/nm-device-infiniband.c'; then $(CYGPATH_W) 'devices/nm-device-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-infiniband.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-infiniband.Tpo $(DEPDIR)/nm-device-infiniband.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-infiniband.c' object='nm-device-infiniband.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-infiniband.obj `if test -f 'devices/nm-device-infiniband.c'; then $(CYGPATH_W) 'devices/nm-device-infiniband.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-infiniband.c'; fi` + +nm-device-macvlan.o: devices/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-macvlan.o -MD -MP -MF $(DEPDIR)/nm-device-macvlan.Tpo -c -o nm-device-macvlan.o `test -f 'devices/nm-device-macvlan.c' || echo '$(srcdir)/'`devices/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-macvlan.Tpo $(DEPDIR)/nm-device-macvlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-macvlan.c' object='nm-device-macvlan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-macvlan.o `test -f 'devices/nm-device-macvlan.c' || echo '$(srcdir)/'`devices/nm-device-macvlan.c + +nm-device-macvlan.obj: devices/nm-device-macvlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-macvlan.obj -MD -MP -MF $(DEPDIR)/nm-device-macvlan.Tpo -c -o nm-device-macvlan.obj `if test -f 'devices/nm-device-macvlan.c'; then $(CYGPATH_W) 'devices/nm-device-macvlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-macvlan.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-macvlan.Tpo $(DEPDIR)/nm-device-macvlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-macvlan.c' object='nm-device-macvlan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-macvlan.obj `if test -f 'devices/nm-device-macvlan.c'; then $(CYGPATH_W) 'devices/nm-device-macvlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-macvlan.c'; fi` + +nm-device-tun.o: devices/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-tun.o -MD -MP -MF $(DEPDIR)/nm-device-tun.Tpo -c -o nm-device-tun.o `test -f 'devices/nm-device-tun.c' || echo '$(srcdir)/'`devices/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-tun.Tpo $(DEPDIR)/nm-device-tun.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-tun.c' object='nm-device-tun.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-tun.o `test -f 'devices/nm-device-tun.c' || echo '$(srcdir)/'`devices/nm-device-tun.c + +nm-device-tun.obj: devices/nm-device-tun.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-tun.obj -MD -MP -MF $(DEPDIR)/nm-device-tun.Tpo -c -o nm-device-tun.obj `if test -f 'devices/nm-device-tun.c'; then $(CYGPATH_W) 'devices/nm-device-tun.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-tun.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-tun.Tpo $(DEPDIR)/nm-device-tun.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-tun.c' object='nm-device-tun.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-tun.obj `if test -f 'devices/nm-device-tun.c'; then $(CYGPATH_W) 'devices/nm-device-tun.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-tun.c'; fi` + +nm-device-veth.o: devices/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-veth.o -MD -MP -MF $(DEPDIR)/nm-device-veth.Tpo -c -o nm-device-veth.o `test -f 'devices/nm-device-veth.c' || echo '$(srcdir)/'`devices/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-veth.Tpo $(DEPDIR)/nm-device-veth.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-veth.c' object='nm-device-veth.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-veth.o `test -f 'devices/nm-device-veth.c' || echo '$(srcdir)/'`devices/nm-device-veth.c + +nm-device-veth.obj: devices/nm-device-veth.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-veth.obj -MD -MP -MF $(DEPDIR)/nm-device-veth.Tpo -c -o nm-device-veth.obj `if test -f 'devices/nm-device-veth.c'; then $(CYGPATH_W) 'devices/nm-device-veth.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-veth.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-veth.Tpo $(DEPDIR)/nm-device-veth.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-veth.c' object='nm-device-veth.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-veth.obj `if test -f 'devices/nm-device-veth.c'; then $(CYGPATH_W) 'devices/nm-device-veth.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-veth.c'; fi` + +nm-device-vlan.o: devices/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vlan.o -MD -MP -MF $(DEPDIR)/nm-device-vlan.Tpo -c -o nm-device-vlan.o `test -f 'devices/nm-device-vlan.c' || echo '$(srcdir)/'`devices/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vlan.Tpo $(DEPDIR)/nm-device-vlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vlan.c' object='nm-device-vlan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vlan.o `test -f 'devices/nm-device-vlan.c' || echo '$(srcdir)/'`devices/nm-device-vlan.c + +nm-device-vlan.obj: devices/nm-device-vlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vlan.obj -MD -MP -MF $(DEPDIR)/nm-device-vlan.Tpo -c -o nm-device-vlan.obj `if test -f 'devices/nm-device-vlan.c'; then $(CYGPATH_W) 'devices/nm-device-vlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-vlan.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vlan.Tpo $(DEPDIR)/nm-device-vlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vlan.c' object='nm-device-vlan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vlan.obj `if test -f 'devices/nm-device-vlan.c'; then $(CYGPATH_W) 'devices/nm-device-vlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-vlan.c'; fi` + +nm-device-vxlan.o: devices/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vxlan.o -MD -MP -MF $(DEPDIR)/nm-device-vxlan.Tpo -c -o nm-device-vxlan.o `test -f 'devices/nm-device-vxlan.c' || echo '$(srcdir)/'`devices/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vxlan.Tpo $(DEPDIR)/nm-device-vxlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vxlan.c' object='nm-device-vxlan.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vxlan.o `test -f 'devices/nm-device-vxlan.c' || echo '$(srcdir)/'`devices/nm-device-vxlan.c + +nm-device-vxlan.obj: devices/nm-device-vxlan.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-device-vxlan.obj -MD -MP -MF $(DEPDIR)/nm-device-vxlan.Tpo -c -o nm-device-vxlan.obj `if test -f 'devices/nm-device-vxlan.c'; then $(CYGPATH_W) 'devices/nm-device-vxlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-vxlan.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-device-vxlan.Tpo $(DEPDIR)/nm-device-vxlan.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='devices/nm-device-vxlan.c' object='nm-device-vxlan.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-device-vxlan.obj `if test -f 'devices/nm-device-vxlan.c'; then $(CYGPATH_W) 'devices/nm-device-vxlan.c'; else $(CYGPATH_W) '$(srcdir)/devices/nm-device-vxlan.c'; fi` + +nm-dhcp-dhclient.o: dhcp-manager/nm-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient.Tpo -c -o nm-dhcp-dhclient.o `test -f 'dhcp-manager/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient.Tpo $(DEPDIR)/nm-dhcp-dhclient.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient.c' object='nm-dhcp-dhclient.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient.o `test -f 'dhcp-manager/nm-dhcp-dhclient.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient.c + +nm-dhcp-dhclient.obj: dhcp-manager/nm-dhcp-dhclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient.Tpo -c -o nm-dhcp-dhclient.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient.Tpo $(DEPDIR)/nm-dhcp-dhclient.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient.c' object='nm-dhcp-dhclient.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient.c'; fi` + +nm-dhcp-dhclient-utils.o: dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.o `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.o `test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhclient-utils.c + +nm-dhcp-dhclient-utils.obj: dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.obj `if test -f 'dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` + +nm-dhcp-dhcpcd.o: dhcp-manager/nm-dhcp-dhcpcd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhcpcd.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhcpcd.Tpo -c -o nm-dhcp-dhcpcd.o `test -f 'dhcp-manager/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhcpcd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhcpcd.Tpo $(DEPDIR)/nm-dhcp-dhcpcd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhcpcd.c' object='nm-dhcp-dhcpcd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhcpcd.o `test -f 'dhcp-manager/nm-dhcp-dhcpcd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-dhcpcd.c + +nm-dhcp-dhcpcd.obj: dhcp-manager/nm-dhcp-dhcpcd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhcpcd.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-dhcpcd.Tpo -c -o nm-dhcp-dhcpcd.obj `if test -f 'dhcp-manager/nm-dhcp-dhcpcd.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhcpcd.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhcpcd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhcpcd.Tpo $(DEPDIR)/nm-dhcp-dhcpcd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-dhcpcd.c' object='nm-dhcp-dhcpcd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhcpcd.obj `if test -f 'dhcp-manager/nm-dhcp-dhcpcd.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-dhcpcd.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-dhcpcd.c'; fi` + +nm-dhcp-systemd.o: dhcp-manager/nm-dhcp-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-systemd.o -MD -MP -MF $(DEPDIR)/nm-dhcp-systemd.Tpo -c -o nm-dhcp-systemd.o `test -f 'dhcp-manager/nm-dhcp-systemd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-systemd.Tpo $(DEPDIR)/nm-dhcp-systemd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-systemd.c' object='nm-dhcp-systemd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-systemd.o `test -f 'dhcp-manager/nm-dhcp-systemd.c' || echo '$(srcdir)/'`dhcp-manager/nm-dhcp-systemd.c + +nm-dhcp-systemd.obj: dhcp-manager/nm-dhcp-systemd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-systemd.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-systemd.Tpo -c -o nm-dhcp-systemd.obj `if test -f 'dhcp-manager/nm-dhcp-systemd.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-systemd.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-systemd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-systemd.Tpo $(DEPDIR)/nm-dhcp-systemd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dhcp-manager/nm-dhcp-systemd.c' object='nm-dhcp-systemd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-systemd.obj `if test -f 'dhcp-manager/nm-dhcp-systemd.c'; then $(CYGPATH_W) 'dhcp-manager/nm-dhcp-systemd.c'; else $(CYGPATH_W) '$(srcdir)/dhcp-manager/nm-dhcp-systemd.c'; fi` + mostlyclean-libtool: -rm -f *.lo @@ -1742,7 +2221,7 @@ check: $(BUILT_SOURCES) all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(dbusservicedir)"; do \ + for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(dbusservicedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1780,8 +2259,8 @@ maintainer-clean-generic: -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - clean-sbinPROGRAMS mostlyclean-am +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + clean-noinstLTLIBRARIES clean-sbinPROGRAMS mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) @@ -1808,7 +2287,7 @@ install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-libexecPROGRAMS install-sbinPROGRAMS install-html: install-html-recursive @@ -1848,27 +2327,29 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-dbusserviceDATA uninstall-sbinPROGRAMS +uninstall-am: uninstall-dbusserviceDATA uninstall-libexecPROGRAMS \ + uninstall-sbinPROGRAMS .MAKE: $(am__recursive_targets) all check install install-am \ install-data-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool \ - clean-noinstLTLIBRARIES clean-sbinPROGRAMS cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-data-hook install-dbusserviceDATA \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ + check-am clean clean-generic clean-libexecPROGRAMS \ + clean-libtool clean-noinstLTLIBRARIES clean-sbinPROGRAMS \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-hook \ + install-dbusserviceDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libexecPROGRAMS \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-dbusserviceDATA \ - uninstall-sbinPROGRAMS + uninstall-libexecPROGRAMS uninstall-sbinPROGRAMS include $(GLIB_MAKEFILE) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 0aaa344f..2c291cdb 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -15,20 +15,30 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2012 Red Hat, Inc. - * Copyright (C) 2005 - 2008 Novell, Inc. + * Copyright 2004 - 2014 Red Hat, Inc. + * Copyright 2005 - 2008 Novell, Inc. */ +#include "config.h" + #include +#include +#include #include #include #include #include #include #include +#include +#include +#include +#include #include "NetworkManagerUtils.h" +#include "nm-platform.h" #include "nm-utils.h" +#include "nm-core-internal.h" #include "nm-logging.h" #include "nm-device.h" #include "nm-setting-connection.h" @@ -36,40 +46,60 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-posix-signals.h" +#include "nm-dbus-glib-types.h" + +/* + * Some toolchains (E.G. uClibc 0.9.33 and earlier) don't export + * CLOCK_BOOTTIME even though the kernel supports it, so provide a + * local definition + */ +#ifndef CLOCK_BOOTTIME +#define CLOCK_BOOTTIME 7 +#endif /* - * nm_ethernet_address_is_valid + * nm_ethernet_address_is_valid: + * @addr: pointer to a binary or ASCII Ethernet address + * @len: length of @addr, or -1 if @addr is ASCII * * Compares an Ethernet address against known invalid addresses. - * + + * Returns: %TRUE if @addr is a valid Ethernet address, %FALSE if it is not. */ gboolean -nm_ethernet_address_is_valid (const struct ether_addr *test_addr) +nm_ethernet_address_is_valid (gconstpointer addr, gssize len) { guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}; guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */ + guchar first_octet; - g_return_val_if_fail (test_addr != NULL, FALSE); + g_return_val_if_fail (addr != NULL, FALSE); + g_return_val_if_fail (len == ETH_ALEN || len == -1, FALSE); /* Compare the AP address the card has with invalid ethernet MAC addresses. */ - if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN)) + if (nm_utils_hwaddr_matches (addr, len, invalid_addr1, ETH_ALEN)) return FALSE; - if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN)) + if (nm_utils_hwaddr_matches (addr, len, invalid_addr2, ETH_ALEN)) return FALSE; - if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN)) + if (nm_utils_hwaddr_matches (addr, len, invalid_addr3, ETH_ALEN)) return FALSE; - if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN)) + if (nm_utils_hwaddr_matches (addr, len, invalid_addr4, ETH_ALEN)) return FALSE; - if (test_addr->ether_addr_octet[0] & 1) /* Multicast addresses */ - return FALSE; + /* Check for multicast address */ + if (len == -1) + first_octet = strtoul (addr, NULL, 16); + else + first_octet = ((guint8 *)addr)[0]; + if (first_octet & 0x01) + return FALSE; return TRUE; } @@ -92,15 +122,15 @@ nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen) * @src: source ip6 address * @plen: prefix length of network * - * Note: this function is self assignment save, to update @src inplace, set both + * Note: this function is self assignment safe, to update @src inplace, set both * @dst and @src to the same destination. */ -void +const struct in6_addr * nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen) { - g_return_if_fail (plen <= 128); - g_return_if_fail (src); - g_return_if_fail (dst); + g_return_val_if_fail (plen <= 128, NULL); + g_return_val_if_fail (src, NULL); + g_return_val_if_fail (dst, NULL); if (plen < 128) { guint nbytes = plen / 8; @@ -116,6 +146,8 @@ nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_ memset (&dst->s6_addr[nbytes], 0, 16 - nbytes); } else if (src != dst) *dst = *src; + + return dst; } @@ -144,6 +176,657 @@ nm_spawn_process (const char *args) return status; } +/** + * nm_utils_get_start_time_for_pid: + * @pid: the process identifier + * + * Originally copied from polkit source (src/polkit/polkitunixprocess.c) + * and adjusted. + * + * Returns: the timestamp when the process started (by parsing /proc/$PID/stat). + * If an error occurs (e.g. the process does not exist), 0 is returned. + * + * The returned start time counts since boot, in the unit HZ (with HZ usually being (1/100) seconds) + **/ +guint64 +nm_utils_get_start_time_for_pid (pid_t pid) +{ + guint64 start_time; + gchar *filename; + gchar *contents; + size_t length; + gchar **tokens; + guint num_tokens; + gchar *p; + gchar *endp; + + start_time = 0; + contents = NULL; + + g_return_val_if_fail (pid > 0, 0); + + filename = g_strdup_printf ("/proc/%"G_GUINT64_FORMAT"/stat", (guint64) pid); + + if (!g_file_get_contents (filename, &contents, &length, NULL)) + goto out; + + /* 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 + * processes trying to fool us + */ + p = strrchr (contents, ')'); + if (p == NULL) + goto out; + p += 2; /* skip ') ' */ + if (p - contents >= (int) length) + goto out; + + tokens = g_strsplit (p, " ", 0); + + num_tokens = g_strv_length (tokens); + + if (num_tokens < 20) + goto out; + + start_time = strtoull (tokens[19], &endp, 10); + if (endp == tokens[19]) + goto out; + + g_strfreev (tokens); + + out: + g_free (filename); + g_free (contents); + + return start_time; +} + +/******************************************************************************************/ + +typedef struct { + pid_t pid; + guint64 log_domain; + union { + struct { + gint64 wait_start_us; + guint source_timeout_kill_id; + } async; + struct { + gboolean success; + int child_status; + } sync; + }; + NMUtilsKillChildAsyncCb callback; + void *user_data; + + char log_name[1]; /* variable-length object, must be last element!! */ +} KillChildAsyncData; + +#define LOG_NAME_FMT "kill child process '%s' (%ld)" +#define LOG_NAME_PROCESS_FMT "kill process '%s' (%ld)" +#define LOG_NAME_ARGS log_name,(long)pid + +static KillChildAsyncData * +_kc_async_data_alloc (pid_t pid, guint64 log_domain, const char *log_name, NMUtilsKillChildAsyncCb callback, void *user_data) +{ + KillChildAsyncData *data; + size_t log_name_len; + + /* append the name at the end of our KillChildAsyncData. */ + log_name_len = strlen (LOG_NAME_FMT) + 20 + strlen (log_name); + data = g_malloc (sizeof (KillChildAsyncData) - 1 + log_name_len); + g_snprintf (data->log_name, log_name_len, LOG_NAME_FMT, LOG_NAME_ARGS); + + data->pid = pid; + data->user_data = user_data; + data->callback = callback; + data->log_domain = log_domain; + + return data; +} + +#define KC_EXIT_TO_STRING_BUF_SIZE 128 +static const char * +_kc_exit_to_string (char *buf, int exit) +#define _kc_exit_to_string(buf, exit) ( G_STATIC_ASSERT_EXPR(sizeof (buf) == KC_EXIT_TO_STRING_BUF_SIZE && sizeof ((buf)[0]) == 1), _kc_exit_to_string (buf, exit) ) +{ + if (WIFEXITED (exit)) + g_snprintf (buf, KC_EXIT_TO_STRING_BUF_SIZE, "normally with status %d", WEXITSTATUS (exit)); + else if (WIFSIGNALED (exit)) + g_snprintf (buf, KC_EXIT_TO_STRING_BUF_SIZE, "by signal %d", WTERMSIG (exit)); + else + g_snprintf (buf, KC_EXIT_TO_STRING_BUF_SIZE, "with unexpected status %d", exit); + return buf; +} + +static const char * +_kc_signal_to_string (int sig) +{ + switch (sig) { + case 0: return "no signal (0)"; + case SIGKILL: return "SIGKILL (" G_STRINGIFY (SIGKILL) ")"; + case SIGTERM: return "SIGTERM (" G_STRINGIFY (SIGTERM) ")"; + default: + return "Unexpected signal"; + } +} + +#define KC_WAITED_TO_STRING 100 +static const char * +_kc_waited_to_string (char *buf, gint64 wait_start_us) +#define _kc_waited_to_string(buf, wait_start_us) ( G_STATIC_ASSERT_EXPR(sizeof (buf) == KC_WAITED_TO_STRING && sizeof ((buf)[0]) == 1), _kc_waited_to_string (buf, wait_start_us) ) +{ + g_snprintf (buf, KC_WAITED_TO_STRING, " (%ld usec elapsed)", (long) (nm_utils_get_monotonic_timestamp_us () - wait_start_us)); + return buf; +} + +static void +_kc_cb_watch_child (GPid pid, gint status, gpointer user_data) +{ + KillChildAsyncData *data = user_data; + char buf_exit[KC_EXIT_TO_STRING_BUF_SIZE], buf_wait[KC_WAITED_TO_STRING]; + + if (data->async.source_timeout_kill_id) + g_source_remove (data->async.source_timeout_kill_id); + + nm_log_dbg (data->log_domain, "%s: terminated %s%s", + data->log_name, _kc_exit_to_string (buf_exit, status), + _kc_waited_to_string (buf_wait, data->async.wait_start_us)); + + if (data->callback) + data->callback (pid, TRUE, status, data->user_data); + + g_free (data); +} + +static gboolean +_kc_cb_timeout_grace_period (void *user_data) +{ + KillChildAsyncData *data = user_data; + int ret, errsv; + + data->async.source_timeout_kill_id = 0; + + if ((ret = kill (data->pid, SIGKILL)) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv != ESRCH) { + nm_log_err (LOGD_CORE | data->log_domain, "%s: kill(SIGKILL) returned unexpected return value %d: (%s, %d)", + data->log_name, ret, strerror (errsv), errsv); + } + } else { + nm_log_dbg (data->log_domain, "%s: process not terminated after %ld usec. Sending SIGKILL signal", + data->log_name, (long) (nm_utils_get_monotonic_timestamp_us () - data->async.wait_start_us)); + } + + return G_SOURCE_REMOVE; +} + +static gboolean +_kc_invoke_callback_idle (gpointer user_data) +{ + KillChildAsyncData *data = user_data; + + if (data->sync.success) { + char buf_exit[KC_EXIT_TO_STRING_BUF_SIZE]; + + nm_log_dbg (data->log_domain, "%s: invoke callback: terminated %s", + data->log_name, _kc_exit_to_string (buf_exit, data->sync.child_status)); + } else + nm_log_dbg (data->log_domain, "%s: invoke callback: killing child failed", data->log_name); + + data->callback (data->pid, data->sync.success, data->sync.child_status, data->user_data); + g_free (data); + + return G_SOURCE_REMOVE; +} + +static void +_kc_invoke_callback (pid_t pid, guint64 log_domain, const char *log_name, NMUtilsKillChildAsyncCb callback, void *user_data, gboolean success, int child_status) +{ + KillChildAsyncData *data; + + if (!callback) + return; + + data = _kc_async_data_alloc (pid, log_domain, log_name, callback, user_data); + data->sync.success = success; + data->sync.child_status = child_status; + + g_idle_add (_kc_invoke_callback_idle, data); +} + +/* nm_utils_kill_child_async: + * @pid: the process id of the process to kill + * @sig: signal to send initially. Set to 0 to send not signal. + * @log_domain: the logging domain used for logging (LOGD_NONE to suppress logging) + * @log_name: for logging, the name of the processes to kill + * @wait_before_kill_msec: Waittime in milliseconds before sending %SIGKILL signal. Set this value + * to zero, not to send %SIGKILL. If @sig is already %SIGKILL, this parameter is ignored. + * @callback: (allow-none): callback after the child terminated. This function will always + * be invoked asynchronously. + * @user_data: passed on to callback + * + * Uses g_child_watch_add(), so note the glib comment: if you obtain pid from g_spawn_async() or + * g_spawn_async_with_pipes() you will need to pass %G_SPAWN_DO_NOT_REAP_CHILD as flag to the spawn + * function for the child watching to work. + * Also note, that you must g_source_remove() any other child watchers for @pid because glib + * supports only one watcher per child. + **/ +void +nm_utils_kill_child_async (pid_t pid, int sig, guint64 log_domain, + const char *log_name, guint32 wait_before_kill_msec, + NMUtilsKillChildAsyncCb callback, void *user_data) +{ + int status = 0, errsv; + pid_t ret; + KillChildAsyncData *data; + char buf_exit[KC_EXIT_TO_STRING_BUF_SIZE]; + + g_return_if_fail (pid > 0); + g_return_if_fail (log_name != NULL); + + /* let's see if the child already terminated... */ + ret = waitpid (pid, &status, WNOHANG); + if (ret > 0) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": process %ld already terminated %s", + LOG_NAME_ARGS, (long) ret, _kc_exit_to_string (buf_exit, status)); + _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, TRUE, status); + return; + } else if (ret != 0) { + errsv = errno; + /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ + if (errsv != ECHILD) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error while waitpid: %s (%d)", + LOG_NAME_ARGS, strerror (errsv), errsv); + _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); + return; + } + } + + /* send the first signal. */ + if (kill (pid, sig) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv != ESRCH) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error sending %s: %s (%d)", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); + return; + } + + /* let's try again with waitpid, probably there was a race... */ + ret = waitpid (pid, &status, 0); + if (ret > 0) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": process %ld already terminated %s", + LOG_NAME_ARGS, (long) ret, _kc_exit_to_string (buf_exit, status)); + _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, TRUE, status); + } else { + errsv = errno; + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed due to unexpected return value %ld by waitpid (%s, %d) after sending %s", + LOG_NAME_ARGS, (long) ret, strerror (errsv), errsv, _kc_signal_to_string (sig)); + _kc_invoke_callback (pid, log_domain, log_name, callback, user_data, FALSE, -1); + } + return; + } + + data = _kc_async_data_alloc (pid, log_domain, log_name, callback, user_data); + data->async.wait_start_us = nm_utils_get_monotonic_timestamp_us (); + + if (sig != SIGKILL && wait_before_kill_msec > 0) { + data->async.source_timeout_kill_id = g_timeout_add (wait_before_kill_msec, _kc_cb_timeout_grace_period, data); + nm_log_dbg (log_domain, "%s: wait for process to terminate after sending %s (send SIGKILL in %ld milliseconds)...", + data->log_name, _kc_signal_to_string (sig), (long) wait_before_kill_msec); + } else { + data->async.source_timeout_kill_id = 0; + nm_log_dbg (log_domain, "%s: wait for process to terminate after sending %s...", + data->log_name, _kc_signal_to_string (sig)); + } + + g_child_watch_add (pid, _kc_cb_watch_child, data); +} + +static inline gulong +_sleep_duration_convert_ms_to_us (guint32 sleep_duration_msec) +{ + if (sleep_duration_msec > 0) { + guint64 x = (gint64) sleep_duration_msec * (guint64) 1000L; + + return x < G_MAXULONG ? (gulong) x : G_MAXULONG; + } + return G_USEC_PER_SEC / 20; +} + +/* nm_utils_kill_child_sync: + * @pid: process id to kill + * @sig: signal to sent initially. If 0, no signal is sent. If %SIGKILL, the + * second %SIGKILL signal is not sent after @wait_before_kill_msec milliseconds. + * @log_domain: log debug information for this domain. Errors and warnings are logged both + * as %LOGD_CORE and @log_domain. + * @log_name: name of the process to kill for logging. + * @child_status: (out) (allow-none): return the exit status of the child, if no error occured. + * @wait_before_kill_msec: Waittime in milliseconds before sending %SIGKILL signal. Set this value + * to zero, not to send %SIGKILL. If @sig is already %SIGKILL, this parameter has not effect. + * @sleep_duration_msec: the synchronous function sleeps repeatedly waiting for the child to terminate. + * Set to zero, to use the default (meaning 20 wakeups per seconds). + * + * Kill a child process synchronously and wait. The function first checks if the child already terminated + * and if it did, return the exit status. Otherwise send one @sig signal. @sig will always be + * sent unless the child already exited. If the child does not exit within @wait_before_kill_msec milliseconds, + * the function will send %SIGKILL and waits for the child indefinitly. If @wait_before_kill_msec is zero, no + * %SIGKILL signal will be sent. + **/ +gboolean +nm_utils_kill_child_sync (pid_t pid, int sig, guint64 log_domain, const char *log_name, + int *child_status, guint32 wait_before_kill_msec, + guint32 sleep_duration_msec) +{ + int status = 0, errsv; + pid_t ret; + gboolean success = FALSE; + gboolean was_waiting = FALSE, send_kill = FALSE; + char buf_exit[KC_EXIT_TO_STRING_BUF_SIZE]; + char buf_wait[KC_WAITED_TO_STRING]; + gint64 wait_start_us; + + g_return_val_if_fail (pid > 0, FALSE); + g_return_val_if_fail (log_name != NULL, FALSE); + + /* check if the child process already terminated... */ + ret = waitpid (pid, &status, WNOHANG); + if (ret > 0) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": process %ld already terminated %s", + LOG_NAME_ARGS, (long) ret, _kc_exit_to_string (buf_exit, status)); + success = TRUE; + goto out; + } else if (ret != 0) { + errsv = errno; + /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ + if (errsv != ECHILD) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": unexpected error while waitpid: %s (%d)", + LOG_NAME_ARGS, strerror (errsv), errsv); + goto out; + } + } + + /* send first signal @sig */ + if (kill (pid, sig) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv != ESRCH) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed to send %s: %s (%d)", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + } else { + /* let's try again with waitpid, probably there was a race... */ + ret = waitpid (pid, &status, 0); + if (ret > 0) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": process %ld already terminated %s", + LOG_NAME_ARGS, (long) ret, _kc_exit_to_string (buf_exit, status)); + success = TRUE; + } else { + errsv = errno; + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed due to unexpected return value %ld by waitpid (%s, %d) after sending %s", + LOG_NAME_ARGS, (long) ret, strerror (errsv), errsv, _kc_signal_to_string (sig)); + } + } + goto out; + } + + wait_start_us = nm_utils_get_monotonic_timestamp_us (); + + /* wait for the process to terminated... */ + if (sig != SIGKILL) { + gint64 wait_until, now; + gulong sleep_time, sleep_duration_usec; + int loop_count = 0; + + sleep_duration_usec = _sleep_duration_convert_ms_to_us (sleep_duration_msec); + wait_until = wait_before_kill_msec <= 0 ? 0 : wait_start_us + (((gint64) wait_before_kill_msec) * 1000L); + + while (TRUE) { + ret = waitpid (pid, &status, WNOHANG); + if (ret > 0) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": after sending %s, process %ld exited %s%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), (long) ret, _kc_exit_to_string (buf_exit, status), + was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); + success = TRUE; + goto out; + } + if (ret == -1) { + errsv = errno; + /* ECHILD means, the process is not a child/does not exist or it has SIGCHILD blocked. */ + if (errsv != ECHILD) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": after sending %s, waitpid failed with %s (%d)%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv, + was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); + goto out; + } + } + + if (!wait_until) + break; + + now = nm_utils_get_monotonic_timestamp_us (); + if (now >= wait_until) + break; + + if (!was_waiting) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": waiting up to %ld milliseconds for process to terminate normally after sending %s...", + LOG_NAME_ARGS, (long) MAX (wait_before_kill_msec, 0), _kc_signal_to_string (sig)); + was_waiting = TRUE; + } + + sleep_time = MIN (wait_until - now, sleep_duration_usec); + if (loop_count < 20) { + /* At the beginning we expect the process to die fast. + * Limit the sleep time, the limit doubles with every iteration. */ + sleep_time = MIN (sleep_time, (((guint64) 1) << loop_count) * G_USEC_PER_SEC / 2000); + loop_count++; + } + g_usleep (sleep_time); + } + + /* send SIGKILL, if called with @wait_before_kill_msec > 0 */ + if (wait_until) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": sending SIGKILL...", LOG_NAME_ARGS); + + send_kill = TRUE; + if (kill (pid, SIGKILL) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv != ESRCH) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": failed to send SIGKILL (after sending %s), %s (%d)", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + goto out; + } + } + } + } + + if (!was_waiting) { + nm_log_dbg (log_domain, LOG_NAME_FMT ": waiting for process to terminate after sending %s%s...", + LOG_NAME_ARGS, _kc_signal_to_string (sig), send_kill ? " and SIGKILL" : ""); + } + + /* block until the child terminates. */ + while ((ret = waitpid (pid, &status, 0)) <= 0) { + errsv = errno; + + if (errsv != EINTR) { + nm_log_err (LOGD_CORE | log_domain, LOG_NAME_FMT ": after sending %s%s, waitpid failed with %s (%d)%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), send_kill ? " and SIGKILL" : "", strerror (errsv), errsv, + _kc_waited_to_string (buf_wait, wait_start_us)); + goto out; + } + } + + nm_log_dbg (log_domain, LOG_NAME_FMT ": after sending %s%s, process %ld exited %s%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), send_kill ? " and SIGKILL" : "", (long) ret, + _kc_exit_to_string (buf_exit, status), _kc_waited_to_string (buf_wait, wait_start_us)); + success = TRUE; +out: + if (child_status) + *child_status = success ? status : -1; + return success; +} + +/* nm_utils_kill_process_sync: + * @pid: process id to kill + * @start_time: the start time of the process to kill (as obtained by nm_utils_get_start_time_for_pid()). + * This is an optional argument, to avoid (somewhat) killing the wrong process as @pid + * might get recycled. You can pass 0, to not provide this parameter. + * @sig: signal to sent initially. If 0, no signal is sent. If %SIGKILL, the + * second %SIGKILL signal is not sent after @wait_before_kill_msec milliseconds. + * @log_domain: log debug information for this domain. Errors and warnings are logged both + * as %LOGD_CORE and @log_domain. + * @log_name: name of the process to kill for logging. + * @wait_before_kill_msec: Waittime in milliseconds before sending %SIGKILL signal. Set this value + * to zero, not to send %SIGKILL. If @sig is already %SIGKILL, this parameter has no effect. + * @sleep_duration_msec: the synchronous function sleeps repeatedly waiting for the child to terminate. + * Set to zero, to use the default (meaning 20 wakeups per seconds). + * + * Kill a non-child process synchronously and wait. This function will not return before the + * process with PID @pid is gone. + **/ +void +nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, guint64 log_domain, + const char *log_name, guint32 wait_before_kill_msec, + guint32 sleep_duration_msec) +{ + int errsv; + guint64 start_time0; + gint64 wait_until, now, wait_start_us; + gulong sleep_time, sleep_duration_usec; + int loop_count = 0; + gboolean was_waiting = FALSE; + char buf_wait[KC_WAITED_TO_STRING]; + + g_return_if_fail (pid > 0); + g_return_if_fail (log_name != NULL); + g_return_if_fail (wait_before_kill_msec > 0); + + start_time0 = nm_utils_get_start_time_for_pid (pid); + if (start_time0 == 0) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": cannot kill process %ld because it seems already gone", + LOG_NAME_ARGS, (long int) pid); + return; + } + if (start_time != 0 && start_time != start_time0) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": don't kill process %ld because the start_time is unexpectedly %lu instead of %ld", + LOG_NAME_ARGS, (long int) pid, (long unsigned) start_time0, (long unsigned) start_time); + return; + } + + if (kill (pid, sig) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv == ESRCH) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": failed to send %s because process seems gone", + LOG_NAME_ARGS, _kc_signal_to_string (sig)); + } else { + nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to send %s: %s (%d)", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv); + } + return; + } + + /* wait for the process to terminated... */ + + wait_start_us = nm_utils_get_monotonic_timestamp_us (); + + sleep_duration_usec = _sleep_duration_convert_ms_to_us (sleep_duration_msec); + wait_until = wait_start_us + (((gint64) wait_before_kill_msec) * 1000L); + + while (TRUE) { + start_time = nm_utils_get_start_time_for_pid (pid); + + if (start_time != start_time0) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": process is gone after sending signal %s%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), + was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); + return; + } + + if (kill (pid, 0) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv == ESRCH) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": process is gone or a zombie after sending signal %s%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), + was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); + } else { + nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to kill(%ld, 0): %s (%d)%s", + LOG_NAME_ARGS, (long int) pid, strerror (errsv), errsv, + was_waiting ? _kc_waited_to_string (buf_wait, wait_start_us) : ""); + } + return; + } + + sleep_time = sleep_duration_usec; + if (wait_until != 0) { + now = nm_utils_get_monotonic_timestamp_us (); + if (sig != SIGKILL && now >= wait_until) { + /* Still not dead. SIGKILL now... */ + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": sending SIGKILL", LOG_NAME_ARGS); + if (kill (pid, SIGKILL) != 0) { + errsv = errno; + /* ESRCH means, process does not exist or is already a zombie. */ + if (errsv != ESRCH) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": process is gone or a zombie%s", + LOG_NAME_ARGS, _kc_waited_to_string (buf_wait, wait_start_us)); + } else { + nm_log_warn (LOGD_CORE | log_domain, LOG_NAME_PROCESS_FMT ": failed to send SIGKILL (after sending %s), %s (%d)%s", + LOG_NAME_ARGS, _kc_signal_to_string (sig), strerror (errsv), errsv, + _kc_waited_to_string (buf_wait, wait_start_us)); + } + return; + } + sig = SIGKILL; + was_waiting = TRUE; + wait_until = 0; + loop_count = 0; /* reset the loop_count. Now we really expect the process to die quickly. */ + } else { + if (!was_waiting) { + nm_log_dbg (log_domain, LOG_NAME_PROCESS_FMT ": waiting up to %ld milliseconds for process to disappear after sending %s...", + LOG_NAME_ARGS, (long) wait_before_kill_msec, _kc_signal_to_string (sig)); + was_waiting = TRUE; + } + sleep_time = MIN (wait_until - now, sleep_duration_usec); + } + } + + if (loop_count < 20) { + /* At the beginning we expect the process to die fast. + * Limit the sleep time, the limit doubles with every iteration. */ + sleep_time = MIN (sleep_time, (((guint64) 1) << loop_count) * G_USEC_PER_SEC / 2000); + loop_count++; + } + g_usleep (sleep_time); + } +} +#undef LOG_NAME_FMT +#undef LOG_NAME_PROCESS_FMT +#undef LOG_NAME_ARGS + +const char *const NM_PATHS_DEFAULT[] = { + PREFIX "/sbin/", + PREFIX "/bin/", + "/sbin/", + "/usr/sbin/", + "/usr/local/sbin/", + "/usr/bin/", + "/usr/local/bin/", + NULL, +}; + +const char * +nm_utils_find_helper(const char *progname, const char *try_first, GError **error) +{ + return nm_utils_file_search_in_paths (progname, try_first, NM_PATHS_DEFAULT, G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, error); +} + +/******************************************************************************************/ + gboolean nm_match_spec_string (const GSList *specs, const char *match) { @@ -160,15 +843,22 @@ nm_match_spec_string (const GSList *specs, const char *match) gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) { - char *hwaddr_match; - gboolean matched; + const GSList *iter; g_return_val_if_fail (hwaddr != NULL, FALSE); - hwaddr_match = g_strdup_printf ("mac:%s", hwaddr); - matched = nm_match_spec_string (specs, hwaddr_match); - g_free (hwaddr_match); - return matched; + for (iter = specs; iter; iter = g_slist_next (iter)) { + const char *spec_str = iter->data; + + if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) + && nm_utils_hwaddr_matches (spec_str + 4, -1, hwaddr, -1)) + return TRUE; + + if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr, -1)) + return TRUE; + } + + return FALSE; } gboolean @@ -179,6 +869,9 @@ nm_match_spec_interface_name (const GSList *specs, const char *interface_name) g_return_val_if_fail (interface_name != NULL, FALSE); + if (nm_match_spec_string (specs, interface_name)) + return TRUE; + iface_match = g_strdup_printf ("interface-name:%s", interface_name); matched = nm_match_spec_string (specs, iface_match); g_free (iface_match); @@ -402,8 +1095,8 @@ value_hash_add_object_property (GHashTable *hash, static char * get_new_connection_name (const GSList *existing, - const char *format, - const char *preferred) + const char *preferred, + const char *fallback_prefix) { GSList *names = NULL; const GSList *iter; @@ -411,6 +1104,8 @@ get_new_connection_name (const GSList *existing, int i = 0; gboolean preferred_found = FALSE; + g_assert (fallback_prefix); + for (iter = existing; iter; iter = g_slist_next (iter)) { NMConnection *candidate = NM_CONNECTION (iter->data); const char *id; @@ -436,7 +1131,12 @@ get_new_connection_name (const GSList *existing, char *temp; gboolean found = FALSE; - temp = g_strdup_printf (format, i); + /* Translators: the first %s is a prefix for the connection id, such + * as "Wired Connection" or "VPN Connection". The %d is a number + * that is combined with the first argument to create a unique + * connection id. */ + temp = g_strdup_printf (C_("connection id fallback", "%s %d"), + fallback_prefix, i); for (iter = names; iter; iter = g_slist_next (iter)) { if (!strcmp (iter->data, temp)) { found = TRUE; @@ -453,68 +1153,38 @@ get_new_connection_name (const GSList *existing, return cname; } -void -nm_utils_normalize_connection (NMConnection *connection, - gboolean default_enable_ipv6) -{ - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; - const char *default_ip6_method = - default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - NMSetting *setting; - const char *method; +static char * +get_new_connection_ifname (const GSList *existing, + const char *prefix) +{ + int i; + char *name; + const GSList *iter; + gboolean found; - s_ip4 = nm_connection_get_setting_ip4_config (connection); - s_ip6 = nm_connection_get_setting_ip6_config (connection); + for (i = 0; i < 500; i++) { + name = g_strdup_printf ("%s%d", prefix, i); - if (nm_setting_connection_get_master (s_con)) { - /* Slave connections don't have IP configuration. */ + if (nm_platform_link_exists (name)) + goto next; - if (s_ip4) { - method = nm_setting_ip4_config_get_method (s_ip4); - if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0) { - nm_log_warn (LOGD_SETTINGS, "ignoring IP4 config on slave '%s'", - nm_connection_get_id (connection)); - } - nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - s_ip4 = NULL; - } + for (iter = existing, found = FALSE; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = iter->data; - if (s_ip6) { - method = nm_setting_ip6_config_get_method (s_ip6); - if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0) { - nm_log_warn (LOGD_SETTINGS, "ignoring IP6 config on slave '%s'", - nm_connection_get_id (connection)); + if (g_strcmp0 (nm_connection_get_interface_name (candidate), name) == 0) { + found = TRUE; + break; } - nm_connection_remove_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); - s_ip6 = NULL; } - } else { - /* Ensure all non-slave connections have IP4 and IP6 settings objects. If no - * IP6 setting was specified, then assume that means IP6 config is allowed - * to fail. But if no IP4 setting was specified, assume the caller was just - * being lazy. - */ - if (!s_ip4) { - setting = nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, setting); - g_object_set (setting, - NM_SETTING_IP4_CONFIG_METHOD, default_ip4_method, - NULL); - } - if (!s_ip6) { - setting = nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, setting); - - g_object_set (setting, - NM_SETTING_IP6_CONFIG_METHOD, default_ip6_method, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, - NULL); - } + if (!found) + return name; + + next: + g_free (name); } + + return NULL; } const char * @@ -522,8 +1192,7 @@ nm_utils_get_ip_config_method (NMConnection *connection, GType ip_setting_type) { NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4, *s_ip6; const char *method; s_con = nm_connection_get_setting_connection (connection); @@ -536,7 +1205,7 @@ nm_utils_get_ip_config_method (NMConnection *connection, else { s_ip4 = nm_connection_get_setting_ip4_config (connection); g_return_val_if_fail (s_ip4 != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO); return method; @@ -550,7 +1219,7 @@ nm_utils_get_ip_config_method (NMConnection *connection, else { s_ip6 = nm_connection_get_setting_ip6_config (connection); g_return_val_if_fail (s_ip6 != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - method = nm_setting_ip6_config_get_method (s_ip6); + method = nm_setting_ip_config_get_method (s_ip6); g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO); return method; @@ -564,12 +1233,16 @@ void nm_utils_complete_generic (NMConnection *connection, const char *ctype, const GSList *existing, - const char *format, - const char *preferred, + const char *preferred_id, + const char *fallback_id_prefix, + const char *ifname_prefix, gboolean default_enable_ipv6) { NMSettingConnection *s_con; - char *id, *uuid; + char *id, *uuid, *ifname; + GHashTable *parameters; + + g_assert (fallback_id_prefix); s_con = nm_connection_get_setting_connection (connection); if (!s_con) { @@ -586,13 +1259,24 @@ nm_utils_complete_generic (NMConnection *connection, /* Add a connection ID if absent */ if (!nm_setting_connection_get_id (s_con)) { - id = get_new_connection_name (existing, format, preferred); + id = get_new_connection_name (existing, preferred_id, fallback_id_prefix); g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL); g_free (id); } + /* Add an interface name, if requested */ + if (ifname_prefix && !nm_setting_connection_get_interface_name (s_con)) { + ifname = get_new_connection_ifname (existing, ifname_prefix); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL); + g_free (ifname); + } + /* Normalize */ - nm_utils_normalize_connection (connection, default_enable_ipv6); + parameters = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD, + default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + nm_connection_normalize (connection, parameters, NULL, NULL); + g_hash_table_destroy (parameters); } char * @@ -682,12 +1366,12 @@ check_ip6_method (NMConnection *orig, { GHashTable *props; const char *orig_ip6_method, *candidate_ip6_method; - NMSettingIP6Config *candidate_ip6; + NMSettingIPConfig *candidate_ip6; gboolean allow = FALSE; props = check_property_in_hash (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); if (!props) return TRUE; @@ -703,7 +1387,7 @@ check_ip6_method (NMConnection *orig, if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 - && (!candidate_ip6 || nm_setting_ip6_config_get_may_fail (candidate_ip6))) { + && (!candidate_ip6 || nm_setting_ip_config_get_may_fail (candidate_ip6))) { allow = TRUE; } @@ -720,7 +1404,7 @@ check_ip6_method (NMConnection *orig, if (allow) { remove_from_hash (settings, props, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); } return allow; } @@ -733,11 +1417,11 @@ check_ip4_method (NMConnection *orig, { GHashTable *props; const char *orig_ip4_method, *candidate_ip4_method; - NMSettingIP4Config *candidate_ip4; + NMSettingIPConfig *candidate_ip4; props = check_property_in_hash (settings, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); if (!props) return TRUE; @@ -752,11 +1436,11 @@ check_ip4_method (NMConnection *orig, if ( strcmp (orig_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0 && strcmp (candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0 - && (!candidate_ip4 || nm_setting_ip4_config_get_may_fail (candidate_ip4)) + && (!candidate_ip4 || nm_setting_ip_config_get_may_fail (candidate_ip4)) && (device_has_carrier == FALSE)) { remove_from_hash (settings, props, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); return TRUE; } return FALSE; @@ -798,7 +1482,7 @@ check_connection_mac_address (NMConnection *orig, GHashTable *settings) { GHashTable *props; - const GByteArray *orig_mac = NULL, *cand_mac = NULL; + const char *orig_mac = NULL, *cand_mac = NULL; NMSettingWired *s_wired_orig, *s_wired_cand; props = check_property_in_hash (settings, @@ -933,6 +1617,31 @@ nm_utils_match_connection (GSList *connections, return best_match; } +int +nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection **b) +{ + NMSettingConnection *a_s_con, *b_s_con; + gboolean a_ac, b_ac; + gint a_ap, b_ap; + + a_s_con = nm_connection_get_setting_connection (*a); + b_s_con = nm_connection_get_setting_connection (*b); + + a_ac = !!nm_setting_connection_get_autoconnect (a_s_con); + b_ac = !!nm_setting_connection_get_autoconnect (b_s_con); + if (a_ac != b_ac) + return ((int) b_ac) - ((int) a_ac); + if (!a_ac) + return 0; + + a_ap = nm_setting_connection_get_autoconnect_priority (a_s_con); + b_ap = nm_setting_connection_get_autoconnect_priority (b_s_con); + if (a_ap != b_ap) + return (a_ap > b_ap) ? -1 : 1; + + return 0; +} + /* nm_utils_ascii_str_to_int64: * * A wrapper for g_ascii_strtoll, that checks whether the whole string @@ -1008,21 +1717,85 @@ nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max return v; } +/** + * nm_utils_uuid_generate_from_strings: + * @string1: a variadic list of strings. Must be NULL terminated. + * + * Returns a variant3 UUID based on the concatenated C strings. + * It does not simply concatenate them, but also includes the + * terminating '\0' character. For example "a", "b", gives + * "a\0b\0\0". + * + * This has the advantage, that the following invocations + * all give different UUIDs: (""), ("",""), ("","a"), ("a",""), + * ("aa"), ("aa", ""), ("", "aa"), ... + */ +char * +nm_utils_uuid_generate_from_strings (const char *string1, ...) +{ + GString *str; + va_list args; + const char *s; + char *uuid; + + if (!string1) + return nm_utils_uuid_generate_from_string (NULL, 0, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + str = g_string_sized_new (120); /* effectively allocates power of 2 (128)*/ + + g_string_append_len (str, string1, strlen (string1) + 1); + + va_start (args, string1); + s = va_arg (args, const char *); + while (s) { + g_string_append_len (str, s, strlen (s) + 1); + s = va_arg (args, const char *); + } + va_end (args); + + uuid = nm_utils_uuid_generate_from_string (str->str, str->len, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + g_string_free (str, TRUE); + return uuid; +} + +/**************************************************************************/ static gint64 monotonic_timestamp_offset_sec; static void monotonic_timestamp_get (struct timespec *tp) { - static gboolean initialized = FALSE; - int err; - - err = clock_gettime (CLOCK_BOOTTIME, tp); + static int clock_mode = 0; + gboolean first_time = FALSE; + int err = 0; + + switch (clock_mode) { + case 0: + /* the clock is not yet initialized (first run) */ + err = clock_gettime (CLOCK_BOOTTIME, tp); + if (err == -1 && errno == EINVAL) { + clock_mode = 2; + err = clock_gettime (CLOCK_MONOTONIC, tp); + } else + clock_mode = 1; + first_time = TRUE; + break; + case 1: + /* default, return CLOCK_BOOTTIME */ + err = clock_gettime (CLOCK_BOOTTIME, tp); + break; + case 2: + /* fallback, return CLOCK_MONOTONIC. Kernels prior to 2.6.39 + * don't support CLOCK_BOOTTIME. */ + err = clock_gettime (CLOCK_MONOTONIC, tp); + break; + } g_assert (err == 0); (void)err; g_assert (tp->tv_nsec >= 0 && tp->tv_nsec < NM_UTILS_NS_PER_SECOND); - if (G_LIKELY (initialized)) + if (G_LIKELY (!first_time)) return; /* Calculate an offset for the time stamp. @@ -1039,7 +1812,6 @@ monotonic_timestamp_get (struct timespec *tp) * wraps (~68 years). **/ monotonic_timestamp_offset_sec = (- ((gint64) tp->tv_sec)) + 1; - initialized = TRUE; if (nm_logging_enabled (LOGL_DEBUG, LOGD_CORE)) { time_t now = time (NULL); @@ -1048,8 +1820,9 @@ monotonic_timestamp_get (struct timespec *tp) strftime (s, sizeof (s), "%Y-%m-%d %H:%M:%S", localtime_r (&now, &tm)); nm_log_dbg (LOGD_CORE, "monotonic timestamp started counting 1.%09ld seconds ago with " - "an offset of %lld.0 seconds to CLOCK_BOOTTIME (local time is %s)", - tp->tv_nsec, (long long) -monotonic_timestamp_offset_sec, s); + "an offset of %lld.0 seconds to %s (local time is %s)", + tp->tv_nsec, (long long) -monotonic_timestamp_offset_sec, + clock_mode == 1 ? "CLOCK_BOOTTIME" : "CLOCK_MONOTONIC", s); } } @@ -1068,7 +1841,7 @@ monotonic_timestamp_get (struct timespec *tp) gint64 nm_utils_get_monotonic_timestamp_ns (void) { - struct timespec tp; + struct timespec tp = { 0 }; monotonic_timestamp_get (&tp); @@ -1095,7 +1868,7 @@ nm_utils_get_monotonic_timestamp_ns (void) gint64 nm_utils_get_monotonic_timestamp_us (void) { - struct timespec tp; + struct timespec tp = { 0 }; monotonic_timestamp_get (&tp); @@ -1122,7 +1895,7 @@ nm_utils_get_monotonic_timestamp_us (void) gint64 nm_utils_get_monotonic_timestamp_ms (void) { - struct timespec tp; + struct timespec tp = { 0 }; monotonic_timestamp_get (&tp); @@ -1149,12 +1922,286 @@ nm_utils_get_monotonic_timestamp_ms (void) gint32 nm_utils_get_monotonic_timestamp_s (void) { - struct timespec tp; + struct timespec tp = { 0 }; monotonic_timestamp_get (&tp); return (((gint64) tp.tv_sec) + monotonic_timestamp_offset_sec); } +typedef struct +{ + const char *name; + NMSetting *setting; + NMSetting *diff_base_setting; + GHashTable *setting_diff; +} LogConnectionSettingData; + +typedef struct +{ + const char *item_name; + NMSettingDiffResult diff_result; +} LogConnectionSettingItem; + +static gint +_log_connection_sort_hashes_fcn (gconstpointer a, gconstpointer b) +{ + const LogConnectionSettingData *v1 = a; + const LogConnectionSettingData *v2 = b; + guint32 p1, p2; + NMSetting *s1, *s2; + + s1 = v1->setting ? v1->setting : v1->diff_base_setting; + s2 = v2->setting ? v2->setting : v2->diff_base_setting; + + g_assert (s1 && s2); + + p1 = _nm_setting_get_setting_priority (s1); + p2 = _nm_setting_get_setting_priority (s2); + + if (p1 != p2) + return p1 > p2 ? 1 : -1; + + return strcmp (v1->name, v2->name); +} + +static GArray * +_log_connection_sort_hashes (NMConnection *connection, NMConnection *diff_base, GHashTable *connection_diff) +{ + GHashTableIter iter; + GArray *sorted_hashes; + LogConnectionSettingData setting_data; + + sorted_hashes = g_array_sized_new (TRUE, FALSE, sizeof (LogConnectionSettingData), g_hash_table_size (connection_diff)); + + g_hash_table_iter_init (&iter, connection_diff); + while (g_hash_table_iter_next (&iter, (gpointer) &setting_data.name, (gpointer) &setting_data.setting_diff)) { + setting_data.setting = nm_connection_get_setting_by_name (connection, setting_data.name); + setting_data.diff_base_setting = diff_base ? nm_connection_get_setting_by_name (diff_base, setting_data.name) : NULL; + g_assert (setting_data.setting || setting_data.diff_base_setting); + g_array_append_val (sorted_hashes, setting_data); + } + + g_array_sort (sorted_hashes, _log_connection_sort_hashes_fcn); + return sorted_hashes; +} + +static gint +_log_connection_sort_names_fcn (gconstpointer a, gconstpointer b) +{ + const LogConnectionSettingItem *v1 = a; + const LogConnectionSettingItem *v2 = b; + + /* we want to first show the items, that disappeared, then the one that changed and + * then the ones that were added. */ + + if ((v1->diff_result & NM_SETTING_DIFF_RESULT_IN_A) != (v2->diff_result & NM_SETTING_DIFF_RESULT_IN_A)) + return (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_A) ? -1 : 1; + if ((v1->diff_result & NM_SETTING_DIFF_RESULT_IN_B) != (v2->diff_result & NM_SETTING_DIFF_RESULT_IN_B)) + return (v1->diff_result & NM_SETTING_DIFF_RESULT_IN_B) ? 1 : -1; + return strcmp (v1->item_name, v2->item_name); +} + +static char * +_log_connection_get_property (NMSetting *setting, const char *name) +{ + GValue val = G_VALUE_INIT; + char *s; + + g_return_val_if_fail (setting, NULL); + + if ( !NM_IS_SETTING_VPN (setting) + && nm_setting_get_secret_flags (setting, name, NULL, NULL)) + return g_strdup ("****"); + + if (!_nm_setting_get_property (setting, name, &val)) + g_return_val_if_reached (FALSE); + + if (G_VALUE_HOLDS_STRING (&val)) { + const char *val_s; + + val_s = g_value_get_string (&val); + if (!val_s) { + /* for NULL, we want to return the unquoted string "NULL". */ + s = g_strdup ("NULL"); + } else { + char *escaped = g_strescape (val_s, "'"); + + s = g_strdup_printf ("'%s'", escaped); + g_free (escaped); + } + } else { + s = g_strdup_value_contents (&val); + if (s == NULL) + s = g_strdup ("NULL"); + else { + char *escaped = g_strescape (s, "'"); + + g_free (s); + s = escaped; + } + } + g_value_unset(&val); + return s; +} + +static void +_log_connection_sort_names (LogConnectionSettingData *setting_data, GArray *sorted_names) +{ + GHashTableIter iter; + LogConnectionSettingItem item; + gpointer p; + + g_array_set_size (sorted_names, 0); + + g_hash_table_iter_init (&iter, setting_data->setting_diff); + while (g_hash_table_iter_next (&iter, (gpointer) &item.item_name, &p)) { + item.diff_result = GPOINTER_TO_UINT (p); + g_array_append_val (sorted_names, item); + } + + g_array_sort (sorted_names, _log_connection_sort_names_fcn); +} + +void +nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix) +{ + GHashTable *connection_diff = NULL; + GArray *sorted_hashes; + GArray *sorted_names = NULL; + int i, j; + gboolean connection_diff_are_same; + gboolean print_header = TRUE; + gboolean print_setting_header; + GString *str1; + + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (!diff_base || (NM_IS_CONNECTION (diff_base) && diff_base != connection)); + + /* For VPN setting types, this is broken, because we cannot (generically) print the content of data/secrets. Bummer... */ + + if (!nm_logging_enabled (level, domain)) + return; + + if (!prefix) + prefix = ""; + if (!name) + name = ""; + + connection_diff_are_same = nm_connection_diff (connection, diff_base, NM_SETTING_COMPARE_FLAG_EXACT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, &connection_diff); + if (connection_diff_are_same) { + if (diff_base) + nm_log (level, domain, "%sconnection '%s' (%p and %p): no difference", prefix, name, connection, diff_base); + else + nm_log (level, domain, "%sconnection '%s' (%p): no properties set", prefix, name, connection); + g_assert (!connection_diff); + return; + } + + /* FIXME: it doesn't nicely show the content of NMSettingVpn, becuase nm_connection_diff() does not + * expand the hash values. */ + + sorted_hashes = _log_connection_sort_hashes (connection, diff_base, connection_diff); + if (sorted_hashes->len <= 0) + goto out; + + sorted_names = g_array_new (FALSE, FALSE, sizeof (LogConnectionSettingItem)); + str1 = g_string_new (NULL); + + for (i = 0; i < sorted_hashes->len; i++) { + LogConnectionSettingData *setting_data = &g_array_index (sorted_hashes, LogConnectionSettingData, i); + + _log_connection_sort_names (setting_data, sorted_names); + print_setting_header = TRUE; + for (j = 0; j < sorted_names->len; j++) { + char *str_conn, *str_diff; + LogConnectionSettingItem *item = &g_array_index (sorted_names, LogConnectionSettingItem, j); + + str_conn = (item->diff_result & NM_SETTING_DIFF_RESULT_IN_A) + ? _log_connection_get_property (setting_data->setting, item->item_name) + : NULL; + str_diff = (item->diff_result & NM_SETTING_DIFF_RESULT_IN_B) + ? _log_connection_get_property (setting_data->diff_base_setting, item->item_name) + : NULL; + + if (print_header) { + GError *err_verify = NULL; + + if (diff_base) + nm_log (level, domain, "%sconnection '%s' (%p < %p):", prefix, name, connection, diff_base); + else + nm_log (level, domain, "%sconnection '%s' (%p):", prefix, name, connection); + print_header = FALSE; + + if (!nm_connection_verify (connection, &err_verify)) { + nm_log (level, domain, "%sconnection %p does not verify: %s", prefix, connection, err_verify->message); + g_clear_error (&err_verify); + } + } +#define _NM_LOG_ALIGN "-25" + if (print_setting_header) { + if (diff_base) { + if (setting_data->setting && setting_data->diff_base_setting) + g_string_printf (str1, "%p < %p", setting_data->setting, setting_data->diff_base_setting); + else if (setting_data->diff_base_setting) + g_string_printf (str1, "*missing* < %p", setting_data->diff_base_setting); + else + g_string_printf (str1, "%p < *missing*", setting_data->setting); + nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s [ %s ]", prefix, setting_data->name, str1->str); + } else + nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s [ %p ]", prefix, setting_data->name, setting_data->setting); + print_setting_header = FALSE; + } + g_string_printf (str1, "%s.%s", setting_data->name, item->item_name); + switch (item->diff_result & (NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B)) { + case NM_SETTING_DIFF_RESULT_IN_B: + nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s < %s", prefix, str1->str, str_diff ? str_diff : "NULL"); + break; + case NM_SETTING_DIFF_RESULT_IN_A: + nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s = %s", prefix, str1->str, str_conn ? str_conn : "NULL"); + break; + default: + nm_log (level, domain, "%s%"_NM_LOG_ALIGN"s = %s < %s", prefix, str1->str, str_conn ? str_conn : "NULL", str_diff ? str_diff : "NULL"); + break; +#undef _NM_LOG_ALIGN + } + g_free (str_conn); + g_free (str_diff); + } + } + + g_array_free (sorted_names, TRUE); + g_string_free (str1, TRUE); +out: + g_hash_table_destroy (connection_diff); + g_array_free (sorted_hashes, TRUE); +} + + +#define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" +#define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/" +G_STATIC_ASSERT (sizeof (IPV4_PROPERTY_DIR) == sizeof (IPV6_PROPERTY_DIR)); + +static const char * +_get_property_path (const char *ifname, + const char *property, + gboolean ipv6) +{ + static char path[sizeof (IPV6_PROPERTY_DIR) + IFNAMSIZ + 32]; + int len; + + ifname = ASSERT_VALID_PATH_COMPONENT (ifname); + property = ASSERT_VALID_PATH_COMPONENT (property); + + len = g_snprintf (path, + sizeof (path), + "%s%s/%s", + ipv6 ? IPV6_PROPERTY_DIR : IPV4_PROPERTY_DIR, + ifname, + property); + g_assert (len < sizeof (path) - 1); + + return path; +} /** * nm_utils_ip6_property_path: @@ -1167,18 +2214,21 @@ nm_utils_get_monotonic_timestamp_s (void) const char * nm_utils_ip6_property_path (const char *ifname, const char *property) { -#define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" - static char path[sizeof (IPV6_PROPERTY_DIR) + IFNAMSIZ + 32]; - int len; - - ifname = ASSERT_VALID_PATH_COMPONENT (ifname); - property = ASSERT_VALID_PATH_COMPONENT (property); - - len = g_snprintf (path, sizeof (path), IPV6_PROPERTY_DIR "%s/%s", - ifname, property); - g_assert (len < sizeof (path) - 1); + return _get_property_path (ifname, property, TRUE); +} - return path; +/** + * nm_utils_ip4_property_path: + * @ifname: an interface name + * @property: a property name + * + * Returns the path to IPv4 property @property on @ifname. Note that + * this uses a static buffer. + */ +const char * +nm_utils_ip4_property_path (const char *ifname, const char *property) +{ + return _get_property_path (ifname, property, FALSE); } const char * @@ -1208,5 +2258,291 @@ fail: else nm_log_err (LOGD_CORE, "Failed asserting path component: \"%s\"", name); g_error ("FATAL: Failed asserting path component: %s", name ? name : "(null)"); + g_assert_not_reached (); +} + +gboolean +nm_utils_is_specific_hostname (const char *name) +{ + if (!name) + return FALSE; + if ( strcmp (name, "(none)") + && strcmp (name, "localhost") + && strcmp (name, "localhost6") + && strcmp (name, "localhost.localdomain") + && strcmp (name, "localhost6.localdomain6")) + return TRUE; + return FALSE; +} + +/******************************************************************/ + +/* Returns the "u" (universal/local) bit value for a Modified EUI-64 */ +static gboolean +get_gre_eui64_u_bit (guint32 addr) +{ + static const struct { + guint32 mask; + guint32 result; + } items[] = { + { 0xff000000 }, { 0x7f000000 }, /* IPv4 loopback */ + { 0xf0000000 }, { 0xe0000000 }, /* IPv4 multicast */ + { 0xffffff00 }, { 0xe0000000 }, /* IPv4 local multicast */ + { 0xffffffff }, { INADDR_BROADCAST }, /* limited broadcast */ + { 0xff000000 }, { 0x00000000 }, /* zero net */ + { 0xff000000 }, { 0x0a000000 }, /* private 10 (RFC3330) */ + { 0xfff00000 }, { 0xac100000 }, /* private 172 */ + { 0xffff0000 }, { 0xc0a80000 }, /* private 192 */ + { 0xffff0000 }, { 0xa9fe0000 }, /* IPv4 link-local */ + { 0xffffff00 }, { 0xc0586300 }, /* anycast 6-to-4 */ + { 0xffffff00 }, { 0xc0000200 }, /* test 192 */ + { 0xfffe0000 }, { 0xc6120000 }, /* test 198 */ + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (items); i++) { + if ((addr & htonl (items[i].mask)) == htonl (items[i].result)) + return 0x00; /* "local" scope */ + } + return 0x02; /* "universal" scope */ +} + +/** + * nm_utils_get_ipv6_interface_identifier: + * @link_type: the hardware link type + * @hwaddr: the hardware address of the interface + * @hwaddr_len: the length (in bytes) of @hwaddr + * @out_iid: on success, filled with the interface identifier; on failure + * zeroed out + * + * Constructs an interface identifier in "Modified EUI-64" format which is + * suitable for constructing IPv6 addresses. Note that the identifier is + * not obscured in any way (eg, RFC3041). + * + * Returns: %TRUE if the interface identifier could be constructed, %FALSE if + * if could not be constructed. + */ +gboolean +nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, + const guint8 *hwaddr, + guint hwaddr_len, + NMUtilsIPv6IfaceId *out_iid) +{ + guint32 addr; + + g_return_val_if_fail (hwaddr != NULL, FALSE); + g_return_val_if_fail (hwaddr_len > 0, FALSE); + g_return_val_if_fail (out_iid != NULL, FALSE); + + out_iid->id = 0; + + switch (link_type) { + case NM_LINK_TYPE_INFINIBAND: + /* Use the port GUID per http://tools.ietf.org/html/rfc4391#section-8, + * making sure to set the 'u' bit to 1. The GUID is the lower 64 bits + * of the IPoIB interface's hardware address. + */ + g_return_val_if_fail (hwaddr_len == INFINIBAND_ALEN, FALSE); + memcpy (out_iid->id_u8, hwaddr + INFINIBAND_ALEN - 8, 8); + out_iid->id_u8[0] |= 0x02; + return TRUE; + case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: + /* Hardware address is the network-endian IPv4 address */ + g_return_val_if_fail (hwaddr_len == 4, FALSE); + addr = * (guint32 *) hwaddr; + out_iid->id_u8[0] = get_gre_eui64_u_bit (addr); + out_iid->id_u8[1] = 0x00; + out_iid->id_u8[2] = 0x5E; + out_iid->id_u8[3] = 0xFE; + memcpy (out_iid->id_u8 + 4, &addr, 4); + return TRUE; + default: + if (hwaddr_len == ETH_ALEN) { + /* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See + * http://tools.ietf.org/html/rfc4291#appendix-A + */ + out_iid->id_u8[0] = hwaddr[0] ^ 0x02; + out_iid->id_u8[1] = hwaddr[1]; + out_iid->id_u8[2] = hwaddr[2]; + out_iid->id_u8[3] = 0xff; + out_iid->id_u8[4] = 0xfe; + out_iid->id_u8[5] = hwaddr[3]; + out_iid->id_u8[6] = hwaddr[4]; + out_iid->id_u8[7] = hwaddr[5]; + return TRUE; + } + break; + } + return FALSE; +} + +void +nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, + const NMUtilsIPv6IfaceId iid) +{ + memcpy (addr->s6_addr + 8, &iid.id_u8, 8); +} + +void +nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, + const struct in6_addr *addr) +{ + memcpy (iid, addr->s6_addr + 8, 8); +} + +/** + * nm_utils_connection_hash_to_dict: + * @hash: a hashed #NMConnection + * + * Returns: a (floating) #GVariant equivalent to @hash. + */ +GVariant * +nm_utils_connection_hash_to_dict (GHashTable *hash) +{ + GValue val = { 0, }; + GVariant *variant; + + if (!hash) + return NULL; + + g_value_init (&val, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + g_value_set_boxed (&val, hash); + variant = dbus_g_value_build_g_variant (&val); + g_value_unset (&val); + + return variant; +} + +/** + * nm_utils_connection_dict_to_hash: + * @dict: a #GVariant-serialized #NMConnection + * + * Returns: a #GHashTable equivalent to @dict. + */ +GHashTable * +nm_utils_connection_dict_to_hash (GVariant *dict) +{ + GValue val = { 0, }; + + if (!dict) + return NULL; + + dbus_g_value_parse_g_variant (dict, &val); + return g_value_get_boxed (&val); } +GSList * +nm_utils_ip4_routes_from_gvalue (const GValue *value) +{ + GPtrArray *routes; + int i; + GSList *list = NULL; + + routes = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; routes && (i < routes->len); i++) { + GArray *array = (GArray *) g_ptr_array_index (routes, i); + guint32 *array_val = (guint32 *) array->data; + NMIPRoute *route; + GError *error = NULL; + + if (array->len < 4) { + g_warning ("Ignoring invalid IP4 route"); + continue; + } + + route = nm_ip_route_new_binary (AF_INET, + &array_val[0], array_val[1], + &array_val[2], array_val[3], + &error); + if (route) + list = g_slist_prepend (list, route); + else { + g_warning ("Ignoring invalid IP4 route: %s", error->message); + g_clear_error (&error); + } + } + + return g_slist_reverse (list); +} + +static gboolean +_nm_utils_gvalue_array_validate (GValueArray *elements, guint n_expected, ...) +{ + va_list args; + GValue *tmp; + int i; + gboolean valid = FALSE; + + if (n_expected != elements->n_values) + return FALSE; + + va_start (args, n_expected); + for (i = 0; i < n_expected; i++) { + tmp = g_value_array_get_nth (elements, i); + if (G_VALUE_TYPE (tmp) != va_arg (args, GType)) + goto done; + } + valid = TRUE; + +done: + va_end (args); + return valid; +} + +GSList * +nm_utils_ip6_routes_from_gvalue (const GValue *value) +{ + GPtrArray *routes; + int i; + GSList *list = NULL; + + routes = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; routes && (i < routes->len); i++) { + GValueArray *route_values = (GValueArray *) g_ptr_array_index (routes, i); + GByteArray *dest, *next_hop; + guint prefix, metric; + NMIPRoute *route; + GError *error = NULL; + + if (!_nm_utils_gvalue_array_validate (route_values, 4, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT)) { + g_warning ("Ignoring invalid IP6 route"); + continue; + } + + dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); + if (dest->len != 16) { + g_warning ("%s: ignoring invalid IP6 dest address of length %d", + __func__, dest->len); + continue; + } + + prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); + + next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); + if (next_hop->len != 16) { + g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", + __func__, next_hop->len); + continue; + } + + metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); + + route = nm_ip_route_new_binary (AF_INET6, + dest->data, prefix, + next_hop->data, metric, + &error); + if (route) + list = g_slist_prepend (list, route); + else { + g_warning ("Ignoring invalid IP6 route: %s", error->message); + g_clear_error (&error); + } + } + + return g_slist_reverse (list); +} diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index a09a30e2..40315c6e 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -15,33 +15,84 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2011 Red Hat, Inc. - * Copyright (C) 2005 - 2008 Novell, Inc. + * Copyright 2004 - 2014 Red Hat, Inc. + * Copyright 2005 - 2008 Novell, Inc. */ -#ifndef NETWORK_MANAGER_UTILS_H -#define NETWORK_MANAGER_UTILS_H +#ifndef __NETWORKMANAGER_UTILS_H__ +#define __NETWORKMANAGER_UTILS_H__ #include #include -#include +#include -#include "nm-ip4-config.h" -#include "nm-setting-ip4-config.h" -#include "nm-ip6-config.h" -#include "nm-setting-ip6-config.h" #include "nm-connection.h" -#include "nm-setting-private.h" +#include "nm-types.h" -gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr); +gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len); in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen); -void nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen); +const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen); + +/** + * nm_utils_ip6_route_metric_normalize: + * @metric: the route metric + * + * For IPv6 route, kernel treats the value 0 as IP6_RT_PRIO_USER (1024). + * Thus, when comparing metric (values), we want to treat zero as NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6. + * + * Returns: @metric, if @metric is not zero, otherwise 1024. + */ +static inline guint32 +nm_utils_ip6_route_metric_normalize (guint32 metric) +{ + return metric ? metric : 1024 /*NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6*/; +} int nm_spawn_process (const char *args); -/* macro to return strlen() of a compile time string. */ -#define STRLEN(str) ( sizeof ("" str) - 1 ) +/* check if @flags has exactly one flag (@check) set. You should call this + * only with @check being a compile time constant and a power of two. */ +#define NM_FLAGS_HAS(flags, check) \ + ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags), (check))) ) + +#define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE ) +#define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE ) + + +/** + * str_if_set: + * @str: input string that will be returned if @str is not %NULL + * @fallback: if @str is %NULL, return @fallback instead + * + * This utility function is useful when printing a string to avoid passing + * %NULL. E.g. printf ("%s", str_if_set (get_string(), "(none)")); + * + * Returns: either @str or @fallback, depending on whether @str is %NULL. + */ +static inline const char * +str_if_set (const char *str, const char *fallback) +{ + return str ? str : fallback; +} + +guint64 nm_utils_get_start_time_for_pid (pid_t pid); + +void nm_utils_kill_process_sync (pid_t pid, guint64 start_time, int sig, guint64 log_domain, + const char *log_name, guint32 wait_before_kill_msec, + guint32 sleep_duration_msec); + +typedef void (*NMUtilsKillChildAsyncCb) (pid_t pid, gboolean success, int child_status, void *user_data); +void nm_utils_kill_child_async (pid_t pid, int sig, guint64 log_domain, const char *log_name, + guint32 wait_before_kill_msec, + NMUtilsKillChildAsyncCb callback, void *user_data); +gboolean nm_utils_kill_child_sync (pid_t pid, int sig, guint64 log_domain, const char *log_name, + int *child_status, guint32 wait_before_kill_msec, + guint32 sleep_duration_msec); + +const char *nm_utils_find_helper (const char *progname, + const char *try_first, + GError **error); gboolean nm_match_spec_string (const GSList *specs, const char *string); gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr); @@ -77,16 +128,15 @@ void value_hash_add_object_property (GHashTable *hash, const char *prop, GType val_type); -void nm_utils_normalize_connection (NMConnection *connection, - gboolean default_enable_ipv6); const char *nm_utils_get_ip_config_method (NMConnection *connection, GType ip_setting_type); void nm_utils_complete_generic (NMConnection *connection, const char *ctype, const GSList *existing, - const char *format, - const char *preferred, + const char *preferred_id, + const char *fallback_id_prefix, + const char *ifname_prefix, gboolean default_enable_ipv6); char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id); @@ -101,8 +151,16 @@ NMConnection *nm_utils_match_connection (GSList *connections, NMUtilsMatchFilterFunc match_filter_func, gpointer match_filter_data); +int nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection **b); + +void nm_utils_log_connection_diff (NMConnection *connection, NMConnection *diff_base, guint32 level, guint64 domain, const char *name, const char *prefix); + gint64 nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); +#define NM_UTILS_UUID_NS "b425e9fb-7598-44b4-9e3b-5a2e3aaa4905" + +char *nm_utils_uuid_generate_from_strings (const char *string1, ...) G_GNUC_NULL_TERMINATED; + #define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000) gint64 nm_utils_get_monotonic_timestamp_ns (void); gint64 nm_utils_get_monotonic_timestamp_us (void); @@ -111,5 +169,45 @@ gint32 nm_utils_get_monotonic_timestamp_s (void); const char *ASSERT_VALID_PATH_COMPONENT (const char *name) G_GNUC_WARN_UNUSED_RESULT; const char *nm_utils_ip6_property_path (const char *ifname, const char *property); +const char *nm_utils_ip4_property_path (const char *ifname, const char *property); + +gboolean nm_utils_is_specific_hostname (const char *name); + +/* IPv6 Interface Identifer helpers */ + +/** + * NMUtilsIPv6IfaceId: + * @id: convenience member for validity checking; never use directly + * @id_u8: the 64-bit Interface Identifier + * + * Holds a 64-bit IPv6 Interface Identifier. The IID is a sequence of bytes + * and should not normally be treated as a %guint64, but this is done for + * convenience of validity checking and initialization. + */ +typedef struct { + union { + guint64 id; + guint8 id_u8[8]; + }; +} NMUtilsIPv6IfaceId; + +#define NM_UTILS_IPV6_IFACE_ID_INIT { .id = 0 } + +gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, + const guint8 *hwaddr, + guint len, + NMUtilsIPv6IfaceId *out_iid); + +void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, + const NMUtilsIPv6IfaceId iid); + +void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, + const struct in6_addr *addr); + +GVariant *nm_utils_connection_hash_to_dict (GHashTable *hash); +GHashTable *nm_utils_connection_dict_to_hash (GVariant *dict); + +GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value); +GSList *nm_utils_ip6_routes_from_gvalue (const GValue *value); -#endif /* NETWORK_MANAGER_UTILS_H */ +#endif /* __NETWORKMANAGER_UTILS_H__ */ diff --git a/src/config/nm-config-device.c b/src/config/nm-config-device.c deleted file mode 100644 index 6914f033..00000000 --- a/src/config/nm-config-device.c +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - */ - -#include "config.h" - -#include "nm-config-device.h" - -#include - -#include - -G_DEFINE_INTERFACE (NMConfigDevice, nm_config_device, G_TYPE_OBJECT) - -static void -nm_config_device_default_init (NMConfigDeviceInterface *iface) -{ -} - -gboolean -nm_config_device_spec_match_list (NMConfigDevice *self, const char **config_specs) -{ - GSList *specs = NULL; - gboolean match; - char buf[NM_UTILS_HWADDR_LEN_MAX + 1], *tmp; - int i; - - g_return_val_if_fail (NM_IS_CONFIG_DEVICE (self), FALSE); - - if (!config_specs) - return FALSE; - - /* For compatibility, we allow an untagged MAC address, and for convenience, - * we allow untagged interface names as well. - */ - for (i = 0; config_specs[i]; i++) { - if (g_strcmp0 (config_specs[i], "*") == 0) - specs = g_slist_prepend (specs, g_strdup (config_specs[i])); - else if (nm_utils_iface_valid_name (config_specs[i])) - specs = g_slist_prepend (specs, g_strdup_printf ("interface-name:%s", config_specs[i])); - else if ( nm_utils_hwaddr_aton (config_specs[i], ARPHRD_ETHER, buf) - || nm_utils_hwaddr_aton (config_specs[i], ARPHRD_INFINIBAND, buf)) { - tmp = g_ascii_strdown (config_specs[i], -1); - specs = g_slist_prepend (specs, g_strdup_printf ("mac:%s", tmp)); - g_free (tmp); - } else - specs = g_slist_prepend (specs, g_strdup (config_specs[i])); - } - - specs = g_slist_reverse (specs); - - match = NM_CONFIG_DEVICE_GET_INTERFACE (self)->spec_match_list (self, specs); - - g_slist_free_full (specs, g_free); - return match; -} - -char * -nm_config_device_get_hwaddr (NMConfigDevice *self) -{ - const guint8 *bytes; - guint len = 0; - - bytes = NM_CONFIG_DEVICE_GET_INTERFACE (self)->get_hw_address (self, &len); - return nm_utils_hwaddr_ntoa_len (bytes, len); -} diff --git a/src/config/nm-config-device.h b/src/config/nm-config-device.h deleted file mode 100644 index 8b5409a0..00000000 --- a/src/config/nm-config-device.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - */ - -#ifndef NM_CONFIG_DEVICE_H -#define NM_CONFIG_DEVICE_H - -#include - -#define NM_TYPE_CONFIG_DEVICE (nm_config_device_get_type ()) -#define NM_CONFIG_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONFIG_DEVICE, NMConfigDevice)) -#define NM_IS_CONFIG_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONFIG_DEVICE)) -#define NM_CONFIG_DEVICE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_CONFIG_DEVICE, NMConfigDeviceInterface)) - -typedef struct _NMConfigDevice NMConfigDevice; -typedef struct _NMConfigDeviceInterface NMConfigDeviceInterface; - -struct _NMConfigDeviceInterface { - GTypeInterface g_iface; - - /* Methods */ - gboolean (*spec_match_list) (NMConfigDevice *device, const GSList *specs); - const guint8 * (* get_hw_address) (NMConfigDevice *device, guint *out_len); -}; - -GType nm_config_device_get_type (void); - -gboolean nm_config_device_spec_match_list (NMConfigDevice *device, const char **config_specs); -char *nm_config_device_get_hwaddr (NMConfigDevice *device); - -#endif /* NM_CONFIG_DEVICE_H */ diff --git a/src/config/nm-config.c b/src/config/nm-config.c deleted file mode 100644 index f6688b75..00000000 --- a/src/config/nm-config.c +++ /dev/null @@ -1,604 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2013 Thomas Bechtold - */ - -#include -#include -#include - -#include "nm-config.h" -#include "nm-logging.h" -#include "nm-utils.h" -#include "nm-glib-compat.h" - -#include -#include - -#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" -#define NM_DEFAULT_SYSTEM_CONF_DIR NMCONFDIR "/conf.d" -#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" -#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state" - -typedef struct { - char *nm_conf_path; - char *config_dir; - char *config_description; - char *no_auto_default_file; - GKeyFile *keyfile; - - char **plugins; - gboolean monitor_connection_files; - char *dhcp_client; - char *dns_mode; - - char *log_level; - char *log_domains; - - char *debug; - - char *connectivity_uri; - gint connectivity_interval; - char *connectivity_response; - - char **no_auto_default; - char **ignore_carrier; -} NMConfigPrivate; - -static NMConfig *singleton = NULL; - -G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT) - -#define NM_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG, NMConfigPrivate)) - -/************************************************************************/ - -const char * -nm_config_get_path (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->nm_conf_path; -} - -const char * -nm_config_get_description (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->config_description; -} - -const char ** -nm_config_get_plugins (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return (const char **) NM_CONFIG_GET_PRIVATE (config)->plugins; -} - -gboolean -nm_config_get_monitor_connection_files (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, FALSE); - - return NM_CONFIG_GET_PRIVATE (config)->monitor_connection_files; -} - -const char * -nm_config_get_dhcp_client (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->dhcp_client; -} - -const char * -nm_config_get_dns_mode (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->dns_mode; -} - -const char * -nm_config_get_log_level (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->log_level; -} - -const char * -nm_config_get_log_domains (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->log_domains; -} - -const char * -nm_config_get_debug (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->debug; -} - -const char * -nm_config_get_connectivity_uri (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->connectivity_uri; -} - -const guint -nm_config_get_connectivity_interval (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, 0); - - /* We store interval as signed internally to track whether it's - * set or not, but report as unsigned to callers. - */ - return MAX (NM_CONFIG_GET_PRIVATE (config)->connectivity_interval, 0); -} - -const char * -nm_config_get_connectivity_response (NMConfig *config) -{ - g_return_val_if_fail (config != NULL, NULL); - - return NM_CONFIG_GET_PRIVATE (config)->connectivity_response; -} - -char * -nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - - return g_key_file_get_string (priv->keyfile, group, key, error); -} - -gboolean -nm_config_get_ignore_carrier (NMConfig *config, NMConfigDevice *device) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - - return nm_config_device_spec_match_list (device, (const char **) priv->ignore_carrier); -} - -/************************************************************************/ - -static void -merge_no_auto_default_state (NMConfig *config) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - GPtrArray *updated; - char **list; - int i, j; - char *data; - - /* If the config already matches everything, we don't need to do anything else. */ - if (priv->no_auto_default && !g_strcmp0 (priv->no_auto_default[0], "*")) - return; - - updated = g_ptr_array_new (); - if (priv->no_auto_default) { - for (i = 0; priv->no_auto_default[i]; i++) - g_ptr_array_add (updated, priv->no_auto_default[i]); - g_free (priv->no_auto_default); - } - - if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) { - list = g_strsplit (data, "\n", -1); - for (i = 0; list[i]; i++) { - if (!*list[i]) - continue; - for (j = 0; j < updated->len; j++) { - if (!strcmp (list[i], updated->pdata[j])) - break; - } - if (j == updated->len) - g_ptr_array_add (updated, list[i]); - } - g_free (list); - g_free (data); - } - - g_ptr_array_add (updated, NULL); - priv->no_auto_default = (char **) g_ptr_array_free (updated, FALSE); -} - -gboolean -nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - - return !nm_config_device_spec_match_list (device, (const char **) priv->no_auto_default); -} - -void -nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - char *current; - GString *updated; - GError *error = NULL; - - if (!nm_config_get_ethernet_can_auto_default (config, device)) - return; - - updated = g_string_new (NULL); - if (g_file_get_contents (priv->no_auto_default_file, ¤t, NULL, NULL)) { - g_string_append (updated, current); - g_free (current); - if (updated->str[updated->len - 1] != '\n') - g_string_append_c (updated, '\n'); - } - - g_string_append (updated, nm_config_device_get_hwaddr (device)); - g_string_append_c (updated, '\n'); - - if (!g_file_set_contents (priv->no_auto_default_file, updated->str, updated->len, &error)) { - nm_log_warn (LOGD_SETTINGS, "Could not update no-auto-default.state file: %s", - error->message); - g_error_free (error); - } - - g_string_free (updated, TRUE); - - merge_no_auto_default_state (config); -} - -/************************************************************************/ - -static char *cli_config_path; -static char *cli_config_dir; -static char *cli_no_auto_default_file; -static char *cli_plugins; -static char *cli_connectivity_uri; -static int cli_connectivity_interval = -1; -static char *cli_connectivity_response; - -static GOptionEntry config_options[] = { - { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") }, - { "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_dir, N_("Config directory location"), N_("/path/to/config/dir") }, - { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli_no_auto_default_file, "no-auto-default.state location", NULL }, - { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") }, - - /* These three are hidden for now, and should eventually just go away. */ - { "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" }, - { "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli_connectivity_interval, N_("The interval between connectivity checks (in seconds)"), "60" }, - { "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_response, N_("The expected start of the response"), N_("Bingo!") }, - {NULL} -}; -GOptionEntry * -nm_config_get_options (void) -{ - return config_options; -} - -/************************************************************************/ - -static gboolean -read_config (NMConfig *config, const char *path, GError **error) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - GKeyFile *kf; - char **groups, **keys; - gsize ngroups, nkeys; - int g, k; - - if (g_file_test (path, G_FILE_TEST_EXISTS) == FALSE) { - g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "file %s not found", path); - return FALSE; - } - - nm_log_dbg (LOGD_SETTINGS, "Reading config file '%s'", path); - - kf = g_key_file_new (); - g_key_file_set_list_separator (kf, ','); - if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) { - g_key_file_free (kf); - return FALSE; - } - - /* Override the current settings with the new ones */ - groups = g_key_file_get_groups (kf, &ngroups); - for (g = 0; groups[g]; g++) { - keys = g_key_file_get_keys (kf, groups[g], &nkeys, NULL); - if (!keys) - continue; - for (k = 0; keys[k]; k++) { - int len = strlen (keys[k]); - if (keys[k][len - 1] == '+') { - char *base_key = g_strndup (keys[k], len - 1); - const char *old_val = g_key_file_get_value (priv->keyfile, groups[g], base_key, NULL); - const char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL); - - if (old_val && *old_val) { - char *combined = g_strconcat (old_val, ",", new_val, NULL); - - g_key_file_set_value (priv->keyfile, groups[g], base_key, combined); - g_free (combined); - } else - g_key_file_set_value (priv->keyfile, groups[g], base_key, new_val); - - g_free (base_key); - continue; - } - - g_key_file_set_value (priv->keyfile, groups[g], keys[k], - g_key_file_get_value (kf, groups[g], keys[k], NULL)); - } - } - g_key_file_free (kf); - - return TRUE; -} - -static gboolean -find_base_config (NMConfig *config, GError **error) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - GError *my_error = NULL; - - /* Try a user-specified config file first */ - if (cli_config_path) { - /* Bad user-specific config file path is a hard error */ - if (read_config (config, cli_config_path, error)) { - priv->nm_conf_path = g_strdup (cli_config_path); - return TRUE; - } else - return FALSE; - } - - /* Even though we prefer NetworkManager.conf, we need to check the - * old nm-system-settings.conf first to preserve compat with older - * setups. In package managed systems dropping a NetworkManager.conf - * onto the system would make NM use it instead of nm-system-settings.conf, - * changing behavior during an upgrade. We don't want that. - */ - - /* Try deprecated nm-system-settings.conf first */ - if (read_config (config, NM_OLD_SYSTEM_CONF_FILE, &my_error)) { - priv->nm_conf_path = g_strdup (NM_OLD_SYSTEM_CONF_FILE); - return TRUE; - } - - if (!g_error_matches (my_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { - g_warning ("Default config file %s invalid: %s\n", - NM_OLD_SYSTEM_CONF_FILE, - my_error->message); - } - g_clear_error (&my_error); - - /* Try the standard config file location next */ - if (read_config (config, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) { - priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE); - return TRUE; - } - - if (!g_error_matches (my_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { - g_warning ("Default config file %s invalid: %s\n", - NM_DEFAULT_SYSTEM_CONF_FILE, - my_error->message); - g_propagate_error (error, my_error); - return FALSE; - } - - /* If for some reason no config file exists, use the default - * config file path. - */ - priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE); - g_warning ("No config file found or given; using %s\n", - NM_DEFAULT_SYSTEM_CONF_FILE); - return TRUE; -} - -/************************************************************************/ - -NMConfig * -nm_config_get (void) -{ - g_assert (singleton); - return singleton; -} - -static int -sort_asciibetically (gconstpointer a, gconstpointer b) -{ - const char *s1 = *(const char **)a; - const char *s2 = *(const char **)b; - - return strcmp (s1, s2); -} - -/* call this function only once! */ -NMConfig * -nm_config_new (GError **error) -{ - NMConfigPrivate *priv = NULL; - GFile *dir; - GFileEnumerator *direnum; - GFileInfo *info; - GPtrArray *confs; - const char *name; - char *value; - int i; - GString *config_description; - - g_assert (!singleton); - singleton = NM_CONFIG (g_object_new (NM_TYPE_CONFIG, NULL)); - priv = NM_CONFIG_GET_PRIVATE (singleton); - - /* First read the base config file */ - if (!find_base_config (singleton, error)) { - g_object_unref (singleton); - singleton = NULL; - return NULL; - } - - /* Now read the overrides in the config dir */ - if (cli_config_dir) - priv->config_dir = g_strdup (cli_config_dir); - else - priv->config_dir = g_strdup (NM_DEFAULT_SYSTEM_CONF_DIR); - - confs = g_ptr_array_new_with_free_func (g_free); - config_description = g_string_new (priv->nm_conf_path); - dir = g_file_new_for_path (priv->config_dir); - direnum = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL); - if (direnum) { - while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) { - name = g_file_info_get_name (info); - if (g_str_has_suffix (name, ".conf")) { - g_ptr_array_add (confs, g_build_filename (priv->config_dir, name, NULL)); - if (confs->len == 1) - g_string_append (config_description, " and conf.d: "); - else - g_string_append (config_description, ", "); - g_string_append (config_description, name); - } - g_object_unref (info); - } - g_object_unref (direnum); - } - g_object_unref (dir); - - g_ptr_array_sort (confs, sort_asciibetically); - priv->config_description = g_string_free (config_description, FALSE); - for (i = 0; i < confs->len; i++) { - if (!read_config (singleton, confs->pdata[i], error)) { - g_object_unref (singleton); - singleton = NULL; - break; - } - } - g_ptr_array_unref (confs); - if (!singleton) - return FALSE; - - /* Handle no-auto-default key and state file */ - priv->no_auto_default = g_key_file_get_string_list (priv->keyfile, "main", "no-auto-default", NULL, NULL); - if (cli_no_auto_default_file) - priv->no_auto_default_file = g_strdup (cli_no_auto_default_file); - else - priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE); - merge_no_auto_default_state (singleton); - - /* Now let command-line options override the config files, and fill in priv. */ - if (cli_plugins && cli_plugins[0]) - g_key_file_set_value (priv->keyfile, "main", "plugins", cli_plugins); - priv->plugins = g_key_file_get_string_list (priv->keyfile, "main", "plugins", NULL, NULL); - - value = g_key_file_get_value (priv->keyfile, "main", "monitor-connection-files", NULL); - if (value) { - if (!strcmp (value, "true") || !strcmp (value, "yes") || !strcmp (value, "on")) - priv->monitor_connection_files = TRUE; - else if (!strcmp (value, "false") || !strcmp (value, "no") || !strcmp (value, "off")) - priv->monitor_connection_files = FALSE; - else { - g_warning ("Unrecognized value for main.monitor-connection-files: %s. Assuming 'false'", value); - priv->monitor_connection_files = FALSE; - } - g_free (value); - } else - priv->monitor_connection_files = FALSE; - - priv->dhcp_client = g_key_file_get_value (priv->keyfile, "main", "dhcp", NULL); - priv->dns_mode = g_key_file_get_value (priv->keyfile, "main", "dns", NULL); - - priv->log_level = g_key_file_get_value (priv->keyfile, "logging", "level", NULL); - priv->log_domains = g_key_file_get_value (priv->keyfile, "logging", "domains", NULL); - - priv->debug = g_key_file_get_value (priv->keyfile, "main", "debug", NULL); - - if (cli_connectivity_uri && cli_connectivity_uri[0]) - g_key_file_set_value (priv->keyfile, "connectivity", "uri", cli_connectivity_uri); - priv->connectivity_uri = g_key_file_get_value (priv->keyfile, "connectivity", "uri", NULL); - - if (cli_connectivity_interval >= 0) - g_key_file_set_integer (priv->keyfile, "connectivity", "interval", cli_connectivity_interval); - priv->connectivity_interval = g_key_file_get_integer (priv->keyfile, "connectivity", "interval", NULL); - - if (cli_connectivity_response && cli_connectivity_response[0]) - g_key_file_set_value (priv->keyfile, "connectivity", "response", cli_connectivity_response); - priv->connectivity_response = g_key_file_get_value (priv->keyfile, "connectivity", "response", NULL); - - priv->ignore_carrier = g_key_file_get_string_list (priv->keyfile, "main", "ignore-carrier", NULL, NULL); - - return singleton; -} - -static void -nm_config_init (NMConfig *config) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); - - priv->keyfile = g_key_file_new (); - g_key_file_set_list_separator (priv->keyfile, ','); - - priv->connectivity_interval = -1; -} - -static void -finalize (GObject *gobject) -{ - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject); - - g_free (priv->nm_conf_path); - g_free (priv->config_dir); - g_free (priv->config_description); - g_free (priv->no_auto_default_file); - g_clear_pointer (&priv->keyfile, g_key_file_unref); - g_strfreev (priv->plugins); - g_free (priv->dhcp_client); - g_free (priv->dns_mode); - g_free (priv->log_level); - g_free (priv->log_domains); - g_free (priv->debug); - g_free (priv->connectivity_uri); - g_free (priv->connectivity_response); - g_strfreev (priv->no_auto_default); - g_strfreev (priv->ignore_carrier); - - singleton = NULL; - - g_clear_pointer (&cli_config_path, g_free); - g_clear_pointer (&cli_config_dir, g_free); - g_clear_pointer (&cli_no_auto_default_file, g_free); - g_clear_pointer (&cli_plugins, g_free); - g_clear_pointer (&cli_connectivity_uri, g_free); - g_clear_pointer (&cli_connectivity_response, g_free); - - G_OBJECT_CLASS (nm_config_parent_class)->finalize (gobject); -} - - -static void -nm_config_class_init (NMConfigClass *config_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (config_class); - - g_type_class_add_private (config_class, sizeof (NMConfigPrivate)); - object_class->finalize = finalize; -} - diff --git a/src/config/nm-config.h b/src/config/nm-config.h deleted file mode 100644 index 2e335c71..00000000 --- a/src/config/nm-config.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2011 Red Hat, Inc. - * Copyright (C) 2013 Thomas Bechtold - */ - -#ifndef NM_CONFIG_H -#define NM_CONFIG_H - -#include -#include - -#include "nm-config-device.h" - -G_BEGIN_DECLS - -#define NM_TYPE_CONFIG (nm_config_get_type ()) -#define NM_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONFIG, NMConfig)) -#define NM_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONFIG, NMConfigClass)) -#define NM_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONFIG)) -#define NM_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONFIG)) -#define NM_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONFIG, NMConfigClass)) - -typedef struct { - GObject parent; -} NMConfig; - -typedef struct { - GObjectClass parent; -} NMConfigClass; - -GType nm_config_get_type (void); - -NMConfig *nm_config_get (void); - -const char *nm_config_get_path (NMConfig *config); -const char *nm_config_get_description (NMConfig *config); -const char **nm_config_get_plugins (NMConfig *config); -gboolean nm_config_get_monitor_connection_files (NMConfig *config); -const char *nm_config_get_dhcp_client (NMConfig *config); -const char *nm_config_get_dns_mode (NMConfig *config); -const char *nm_config_get_log_level (NMConfig *config); -const char *nm_config_get_log_domains (NMConfig *config); -const char *nm_config_get_debug (NMConfig *config); -const char *nm_config_get_connectivity_uri (NMConfig *config); -const guint nm_config_get_connectivity_interval (NMConfig *config); -const char *nm_config_get_connectivity_response (NMConfig *config); - -gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMConfigDevice *device); -void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMConfigDevice *device); - -gboolean nm_config_get_ignore_carrier (NMConfig *config, NMConfigDevice *device); - -char *nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error); - -/* for main.c only */ -GOptionEntry *nm_config_get_options (void); -NMConfig *nm_config_new (GError **error); - -G_END_DECLS - -#endif /* NM_CONFIG_H */ - diff --git a/src/config/tests/Makefile.am b/src/config/tests/Makefile.am deleted file mode 100644 index 6e64812b..00000000 --- a/src/config/tests/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/config \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(GLIB_CFLAGS) \ - -DSRCDIR=\""$(srcdir)"\" - -noinst_PROGRAMS = \ - test-config - -test_config_SOURCES = \ - nm-test-device.c \ - nm-test-device.h \ - test-config.c - -test_config_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - -TESTS = test-config - -EXTRA_DIST = \ - NetworkManager.conf \ - bad.conf \ - conf.d/00-overrides.conf \ - conf.d/10-more.conf \ - conf.d/90-last.conf diff --git a/src/config/tests/Makefile.in b/src/config/tests/Makefile.in deleted file mode 100644 index 4ac0ce15..00000000 --- a/src/config/tests/Makefile.in +++ /dev/null @@ -1,864 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -noinst_PROGRAMS = test-config$(EXEEXT) -TESTS = test-config$(EXEEXT) -subdir = src/config/tests -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ - $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -PROGRAMS = $(noinst_PROGRAMS) -am_test_config_OBJECTS = nm-test-device.$(OBJEXT) \ - test-config.$(OBJEXT) -test_config_OBJECTS = $(am_test_config_OBJECTS) -test_config_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(test_config_SOURCES) -DIST_SOURCES = $(test_config_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - mgn=''; \ - brg=''; \ - std=''; \ - fi; \ -} -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALL_LINGUAS = @ALL_LINGUAS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -GTKDOC_MKPDF = @GTKDOC_MKPDF@ -GTKDOC_REBASE = @GTKDOC_REBASE@ -GUDEV_CFLAGS = @GUDEV_CFLAGS@ -GUDEV_LIBS = @GUDEV_LIBS@ -HTML_DIR = @HTML_DIR@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ -INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ -INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ -INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ -IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ -KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -NM_VERSION = @NM_VERSION@ -NSS_CFLAGS = @NSS_CFLAGS@ -NSS_LIBS = @NSS_LIBS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POLKIT_CFLAGS = @POLKIT_CFLAGS@ -POLKIT_LIBS = @POLKIT_LIBS@ -POSUB = @POSUB@ -PPPD_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/config \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(GLIB_CFLAGS) \ - -DSRCDIR=\""$(srcdir)"\" - -test_config_SOURCES = \ - nm-test-device.c \ - nm-test-device.h \ - test-config.c - -test_config_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - -EXTRA_DIST = \ - NetworkManager.conf \ - bad.conf \ - conf.d/00-overrides.conf \ - conf.d/10-more.conf \ - conf.d/90-last.conf - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/config/tests/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/config/tests/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -test-config$(EXEEXT): $(test_config_OBJECTS) $(test_config_DEPENDENCIES) $(EXTRA_test_config_DEPENDENCIES) - @rm -f test-config$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_config_OBJECTS) $(test_config_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-test-device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-config.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ - else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/config/tests/NetworkManager.conf b/src/config/tests/NetworkManager.conf deleted file mode 100644 index 401ba48a..00000000 --- a/src/config/tests/NetworkManager.conf +++ /dev/null @@ -1,15 +0,0 @@ -[main] -dhcp=dhclient -plugins=foo,bar,baz -no-auto-default=11:11:11:11:11:11 - -[logging] -level=INFO - -[connectivity] -uri=http://example.com -interval=100 -response=Hello - -[extra-section] -extra-key=some value diff --git a/src/config/tests/bad.conf b/src/config/tests/bad.conf deleted file mode 100644 index 20d6a67a..00000000 --- a/src/config/tests/bad.conf +++ /dev/null @@ -1 +0,0 @@ -This is not a keyfile. diff --git a/src/config/tests/conf.d/00-overrides.conf b/src/config/tests/conf.d/00-overrides.conf deleted file mode 100644 index 0aa19d48..00000000 --- a/src/config/tests/conf.d/00-overrides.conf +++ /dev/null @@ -1,11 +0,0 @@ -[main] -dhcp=dhcpcd - -[logging] -domains=PLATFORM,DNS,WIFI - -[order] -a=0 -b=0 -c=0 - diff --git a/src/config/tests/conf.d/10-more.conf b/src/config/tests/conf.d/10-more.conf deleted file mode 100644 index b1424a4b..00000000 --- a/src/config/tests/conf.d/10-more.conf +++ /dev/null @@ -1,11 +0,0 @@ -[main] -extra=hello -new+=something - -[connectivity] -uri=http://example.net - -[order] -a=10 -b=10 - diff --git a/src/config/tests/conf.d/90-last.conf b/src/config/tests/conf.d/90-last.conf deleted file mode 100644 index dc1de394..00000000 --- a/src/config/tests/conf.d/90-last.conf +++ /dev/null @@ -1,5 +0,0 @@ -[main] -plugins+=one,two - -[order] -a=90 diff --git a/src/config/tests/nm-test-device.c b/src/config/tests/nm-test-device.c deleted file mode 100644 index b671f255..00000000 --- a/src/config/tests/nm-test-device.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - */ - -#include "config.h" - -#include -#include - -#include "nm-test-device.h" -#include "nm-config-device.h" -#include "nm-utils.h" - -static void nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (NMTestDevice, nm_test_device, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (NM_TYPE_CONFIG_DEVICE, nm_test_device_config_device_interface_init)) - -static void -nm_test_device_init (NMTestDevice *self) -{ -} - -static void -finalize (GObject *object) -{ - NMTestDevice *self = NM_TEST_DEVICE (object); - - g_free (self->hwaddr); - g_free (self->hwaddr_bytes); - - G_OBJECT_CLASS (nm_test_device_parent_class)->finalize (object); -} - -static void -nm_test_device_class_init (NMTestDeviceClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = finalize; -} - -static gboolean -spec_match_list (NMConfigDevice *device, const GSList *specs) -{ - NMTestDevice *self = NM_TEST_DEVICE (device); - const GSList *iter; - const char *spec; - - for (iter = specs; iter; iter = iter->next) { - spec = iter->data; - if (g_str_has_prefix (spec, "mac:") && !strcmp (spec + 4, self->hwaddr)) - return TRUE; - } - return FALSE; -} - -static const guint8 * -get_hw_address (NMConfigDevice *device, guint *out_len) -{ - NMTestDevice *self = NM_TEST_DEVICE (device); - - if (out_len) - *out_len = ETH_ALEN; - return self->hwaddr_bytes; -} - -static void -nm_test_device_config_device_interface_init (NMConfigDeviceInterface *iface) -{ - iface->spec_match_list = spec_match_list; - iface->get_hw_address = get_hw_address; -} - -NMTestDevice * -nm_test_device_new (const char *hwaddr) -{ - NMTestDevice *self = g_object_new (NM_TYPE_TEST_DEVICE, NULL); - - self->hwaddr = g_strdup (hwaddr); - self->hwaddr_bytes = g_malloc (ETH_ALEN); - nm_utils_hwaddr_aton (hwaddr, ARPHRD_ETHER, self->hwaddr_bytes); - - return self; -} diff --git a/src/config/tests/nm-test-device.h b/src/config/tests/nm-test-device.h deleted file mode 100644 index ad63bf5f..00000000 --- a/src/config/tests/nm-test-device.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - */ - -#ifndef NM_TEST_DEVICE_H -#define NM_TEST_DEVICE_H - -#include - -G_BEGIN_DECLS - -#define NM_TYPE_TEST_DEVICE (nm_test_device_get_type ()) -#define NM_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEST_DEVICE, NMTestDevice)) -#define NM_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) -#define NM_IS_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_TEST_DEVICE)) -#define NM_IS_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_TEST_DEVICE)) -#define NM_TEST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) - -typedef struct { - GObject parent; - - char *hwaddr; - guint8 *hwaddr_bytes; -} NMTestDevice; - -typedef struct { - GObjectClass parent; -} NMTestDeviceClass; - -GType nm_test_device_get_type (void); - -NMTestDevice *nm_test_device_new (const char *hwaddr); - -G_END_DECLS - -#endif /* NM_DEVICE_H */ diff --git a/src/config/tests/test-config.c b/src/config/tests/test-config.c deleted file mode 100644 index fb6baacc..00000000 --- a/src/config/tests/test-config.c +++ /dev/null @@ -1,305 +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, 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2013 Red Hat, Inc. - * - */ - -#include "config.h" - -#include - -#include - -#include -#include "nm-test-device.h" - -static void -setup_config (const char *config_file, const char *config_dir, ...) -{ - va_list ap; - GPtrArray *args; - char **argv, *arg; - int argc; - GOptionContext *context; - gboolean success; - - args = g_ptr_array_new (); - g_ptr_array_add (args, "test-config"); - g_ptr_array_add (args, "--config"); - g_ptr_array_add (args, (char *)config_file); - g_ptr_array_add (args, "--config-dir"); - g_ptr_array_add (args, (char *)config_dir); - - va_start (ap, config_dir); - while ((arg = va_arg (ap, char *))) - g_ptr_array_add (args, arg); - va_end (ap); - - argv = (char **)args->pdata; - argc = args->len; - - context = g_option_context_new (NULL); - g_option_context_add_main_entries (context, nm_config_get_options (), NULL); - success = g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (!success) - g_printerr ("Invalid options.\n"); - - g_ptr_array_free (args, TRUE); -} - -static void -test_config_simple (void) -{ - NMConfig *config; - GError *error = NULL; - const char **plugins; - char *value; - - setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL); - config = nm_config_new (&error); - g_assert_no_error (error); - - g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); - g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient"); - g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); - g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100); - - plugins = nm_config_get_plugins (config); - g_assert_cmpint (g_strv_length ((char **)plugins), ==, 3); - g_assert_cmpstr (plugins[0], ==, "foo"); - g_assert_cmpstr (plugins[1], ==, "bar"); - g_assert_cmpstr (plugins[2], ==, "baz"); - - value = nm_config_get_value (config, "extra-section", "extra-key", NULL); - g_assert_cmpstr (value, ==, "some value"); - g_free (value); - - value = nm_config_get_value (config, "extra-section", "no-key", &error); - g_assert (!value); - g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); - g_clear_error (&error); - - value = nm_config_get_value (config, "no-section", "no-key", &error); - g_assert (!value); - g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); - g_clear_error (&error); - - g_object_unref (config); -} - -static void -test_config_non_existent (void) -{ - NMConfig *config; - GError *error = NULL; - - setup_config (SRCDIR "/no-such-file", "/no/such/dir", NULL); - config = nm_config_new (&error); - g_assert (!config); - g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND); -} - -static void -test_config_parse_error (void) -{ - NMConfig *config; - GError *error = NULL; - - setup_config (SRCDIR "/bad.conf", "/no/such/dir", NULL); - config = nm_config_new (&error); - g_assert (!config); - g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); -} - -static void -test_config_override (void) -{ - NMConfig *config; - GError *error = NULL; - const char **plugins; - - setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", - "--plugins", "alpha,beta,gamma,delta", - "--connectivity-interval", "12", - NULL); - config = nm_config_new (&error); - g_assert_no_error (error); - - g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); - g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient"); - g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); - g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 12); - - plugins = nm_config_get_plugins (config); - g_assert_cmpint (g_strv_length ((char **)plugins), ==, 4); - g_assert_cmpstr (plugins[0], ==, "alpha"); - g_assert_cmpstr (plugins[1], ==, "beta"); - g_assert_cmpstr (plugins[2], ==, "gamma"); - g_assert_cmpstr (plugins[3], ==, "delta"); - - g_object_unref (config); -} - -static void -test_config_no_auto_default (void) -{ - NMConfig *config; - GError *error = NULL; - int fd, nwrote; - char *state_file; - NMTestDevice *dev1, *dev2, *dev3, *dev4; - - fd = g_file_open_tmp (NULL, &state_file, &error); - g_assert_no_error (error); - - nwrote = write (fd, "22:22:22:22:22:22\n", 18); - g_assert_cmpint (nwrote, ==, 18); - nwrote = write (fd, "44:44:44:44:44:44\n", 18); - g_assert_cmpint (nwrote, ==, 18); - close (fd); - - setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", - "--no-auto-default", state_file, - NULL); - config = nm_config_new (&error); - g_assert_no_error (error); - - dev1 = nm_test_device_new ("11:11:11:11:11:11"); - dev2 = nm_test_device_new ("22:22:22:22:22:22"); - dev3 = nm_test_device_new ("33:33:33:33:33:33"); - dev4 = nm_test_device_new ("44:44:44:44:44:44"); - - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); - g_assert (nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); - - nm_config_set_ethernet_no_auto_default (config, NM_CONFIG_DEVICE (dev3)); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); - - g_object_unref (config); - - setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", - "--no-auto-default", state_file, - NULL); - config = nm_config_new (&error); - g_assert_no_error (error); - - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev1))); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev2))); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev3))); - g_assert (!nm_config_get_ethernet_can_auto_default (config, NM_CONFIG_DEVICE (dev4))); - - g_object_unref (config); - - g_object_unref (dev1); - g_object_unref (dev2); - g_object_unref (dev3); - g_object_unref (dev4); - - unlink (state_file); - g_free (state_file); -} - -static void -test_config_confdir (void) -{ - NMConfig *config; - GError *error = NULL; - const char **plugins; - char *value; - - setup_config (SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL); - config = nm_config_new (&error); - g_assert_no_error (error); - - g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); - g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd"); - g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); - g_assert_cmpstr (nm_config_get_log_domains (config), ==, "PLATFORM,DNS,WIFI"); - g_assert_cmpstr (nm_config_get_connectivity_uri (config), ==, "http://example.net"); - g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100); - - plugins = nm_config_get_plugins (config); - g_assert_cmpint (g_strv_length ((char **)plugins), ==, 5); - g_assert_cmpstr (plugins[0], ==, "foo"); - g_assert_cmpstr (plugins[1], ==, "bar"); - g_assert_cmpstr (plugins[2], ==, "baz"); - g_assert_cmpstr (plugins[3], ==, "one"); - g_assert_cmpstr (plugins[4], ==, "two"); - - value = nm_config_get_value (config, "main", "extra", NULL); - g_assert_cmpstr (value, ==, "hello"); - g_free (value); - - value = nm_config_get_value (config, "main", "new", NULL); - g_assert_cmpstr (value, ==, "something"); /* not ",something" */ - g_free (value); - - value = nm_config_get_value (config, "order", "a", NULL); - g_assert_cmpstr (value, ==, "90"); - g_free (value); - value = nm_config_get_value (config, "order", "b", NULL); - g_assert_cmpstr (value, ==, "10"); - g_free (value); - value = nm_config_get_value (config, "order", "c", NULL); - g_assert_cmpstr (value, ==, "0"); - g_free (value); - - g_object_unref (config); -} - -static void -test_config_confdir_parse_error (void) -{ - NMConfig *config; - GError *error = NULL; - - /* Using SRCDIR as the conf dir will pick up bad.conf */ - setup_config (SRCDIR "/NetworkManager.conf", SRCDIR, NULL); - config = nm_config_new (&error); - g_assert (!config); - g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); -} - -int -main (int argc, char **argv) -{ -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/config/simple", test_config_simple); - g_test_add_func ("/config/non-existent", test_config_non_existent); - g_test_add_func ("/config/parse-error", test_config_parse_error); - g_test_add_func ("/config/no-auto-default", test_config_no_auto_default); - g_test_add_func ("/config/confdir", test_config_confdir); - g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error); - - /* 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. - */ - g_test_add_func ("/config/override", test_config_override); - - return g_test_run (); -} - diff --git a/src/devices/adsl/Makefile.am b/src/devices/adsl/Makefile.am index 0430f47d..07a8f9ee 100644 --- a/src/devices/adsl/Makefile.am +++ b/src/devices/adsl/Makefile.am @@ -5,20 +5,15 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/ppp-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(GUDEV_CFLAGS) GLIB_GENERATED = nm-adsl-enum-types.h nm-adsl-enum-types.c diff --git a/src/devices/adsl/Makefile.in b/src/devices/adsl/Makefile.in index 708a45d2..7942c559 100644 --- a/src/devices/adsl/Makefile.in +++ b/src/devices/adsl/Makefile.in @@ -217,6 +217,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -340,6 +342,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -359,6 +362,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -385,7 +389,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -467,20 +471,15 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/ppp-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-adsl"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(GUDEV_CFLAGS) GLIB_GENERATED = nm-adsl-enum-types.h nm-adsl-enum-types.c diff --git a/src/devices/adsl/exports.ver b/src/devices/adsl/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/adsl/exports.ver +++ b/src/devices/adsl/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index e8db3596..6f34c02b 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -18,7 +18,7 @@ * Copyright (C) 2009 - 2013 Red Hat, Inc. */ -#include +#include "config.h" #include #include @@ -28,11 +28,11 @@ #include "nm-device-adsl.h" #include "nm-device-factory.h" #include "nm-logging.h" +#include "nm-glib-compat.h" typedef struct { GUdevClient *client; GSList *devices; - guint start_id; } NMAtmManagerPrivate; #define NM_ATM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ATM_MANAGER, NMAtmManagerPrivate)) @@ -46,20 +46,12 @@ G_DEFINE_TYPE_EXTENDED (NMAtmManager, nm_atm_manager, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_ADSL - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_ATM_MANAGER, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ static gboolean @@ -163,9 +155,10 @@ adsl_remove (NMAtmManager *self, GUdevDevice *udev_device) } } -static gboolean -query_devices (NMAtmManager *self) +static void +start (NMDeviceFactory *factory) { + NMAtmManager *self = NM_ATM_MANAGER (factory); NMAtmManagerPrivate *priv = NM_ATM_MANAGER_GET_PRIVATE (self); GUdevEnumerator *enumerator; GList *devices, *iter; @@ -180,8 +173,6 @@ query_devices (NMAtmManager *self) } g_list_free (devices); g_object_unref (enumerator); - - return G_SOURCE_REMOVE; } static void @@ -212,6 +203,12 @@ handle_uevent (GUdevClient *client, adsl_remove (self, device); } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_ADSL; +} + /*********************************************************************/ static void @@ -222,13 +219,13 @@ nm_atm_manager_init (NMAtmManager *self) priv->client = g_udev_client_new (subsys); g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); - - priv->start_id = g_idle_add ((GSourceFunc) query_devices, self); } static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void @@ -242,11 +239,6 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_func (priv->client, handle_uevent, self); g_clear_object (&priv->client); - if (priv->start_id) { - g_source_remove (priv->start_id); - priv->start_id = 0; - } - for (iter = priv->devices; iter; iter = iter->next) g_object_weak_unref (G_OBJECT (iter->data), device_destroyed, self); g_clear_pointer (&priv->devices, g_slist_free); diff --git a/src/devices/adsl/nm-atm-manager.h b/src/devices/adsl/nm-atm-manager.h index 00525220..e4ec3e6a 100644 --- a/src/devices/adsl/nm-atm-manager.h +++ b/src/devices/adsl/nm-atm-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_ATM_MANAGER_H -#define NM_ATM_MANAGER_H +#ifndef __NETWORKMANAGER_ATM_MANAGER_H__ +#define __NETWORKMANAGER_ATM_MANAGER_H__ #include #include @@ -38,5 +38,5 @@ typedef struct { GObjectClass parent; } NMAtmManagerClass; -#endif /* NM_ATM_MANAGER_H */ +#endif /* __NETWORKMANAGER_ATM_MANAGER_H__ */ diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 0c35bb7a..e664ff48 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -18,7 +18,7 @@ * Pantelis Koukousoulas */ -#include +#include "config.h" #include #include @@ -44,9 +44,13 @@ #include "ppp-manager/nm-ppp-manager.h" #include "nm-setting-adsl.h" +#include "nm-utils.h" #include "nm-device-adsl-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF (NMDeviceAdsl); + G_DEFINE_TYPE (NMDeviceAdsl, nm_device_adsl, NM_TYPE_DEVICE) #define NM_DEVICE_ADSL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_ADSL, NMDeviceAdslPrivate)) @@ -72,7 +76,9 @@ typedef struct { static guint32 get_generic_capabilities (NMDevice *dev) { - return (NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER); + return ( NM_DEVICE_CAP_CARRIER_DETECT + | NM_DEVICE_CAP_NONSTANDARD_CARRIER + | NM_DEVICE_CAP_IS_NON_KERNEL); } static gboolean @@ -119,7 +125,8 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, NM_SETTING_ADSL_SETTING_NAME, existing_connections, - _("ADSL connection %d"), + NULL, + _("ADSL connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -142,18 +149,14 @@ set_nas_iface (NMDeviceAdsl *self, int idx, const char *name) g_warn_if_fail (priv->nas_ifname == NULL); priv->nas_ifname = g_strdup (name); - - /* Update NAS interface's MAC address */ - nm_device_update_hw_address (NM_DEVICE (self)); } static gboolean br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); struct atm_newif_br2684 ni; - int err, fd; + int err, fd, errsv; gboolean success = FALSE; guint num = 0; @@ -161,8 +164,8 @@ br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); if (fd < 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to open ATM control socket (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); return FALSE; } @@ -183,17 +186,19 @@ br2684_create_iface (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) err = ioctl (fd, ATM_NEWBACKENDIF, &ni); if (err == 0) { set_nas_iface (self, -1, ni.ifname); - nm_log_info (LOGD_ADSL, "(%s): using NAS interface %s (%d)", - iface, priv->nas_ifname, priv->nas_ifindex); + _LOGI (LOGD_ADSL, "using NAS interface %s (%d)", + priv->nas_ifname, priv->nas_ifindex); success = TRUE; break; - } else if (errno == -EEXIST) { - /* Try again */ - num++; } else { - nm_log_warn (LOGD_ADSL, "(%s): failed to create br2684 interface (%d)", - iface, errno); - break; + errsv = errno; + if (errsv == -EEXIST) { + /* Try again */ + num++; + } else { + _LOGW (LOGD_ADSL, "failed to create br2684 interface (%d)", errsv); + break; + } } } @@ -205,11 +210,10 @@ static gboolean br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) { NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); struct sockaddr_atmpvc addr; struct atm_backend_br2684 be; struct atm_qos qos; - int err, bufsize = 8192; + int errsv, err, bufsize = 8192; const char *encapsulation; gboolean is_llc; @@ -218,15 +222,15 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); if (priv->brfd < 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to open ATM control socket (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); return FALSE; } err = setsockopt (priv->brfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof (bufsize)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set SNDBUF option (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set SNDBUF option (%d)", errsv); goto error; } @@ -240,8 +244,8 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) err = setsockopt (priv->brfd, SOL_ATM, SO_ATMQOS, &qos, sizeof (qos)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set QoS (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set QoS (%d)", errsv); goto error; } @@ -254,15 +258,14 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) addr.sap_addr.vpi = (guint16) nm_setting_adsl_get_vpi (s_adsl); addr.sap_addr.vci = (int) nm_setting_adsl_get_vci (s_adsl); - nm_log_dbg (LOGD_ADSL, "(%s): assigning address %d.%d.%d encapsulation %s", - nm_device_get_iface (NM_DEVICE (self)), - priv->atm_index, addr.sap_addr.vpi, addr.sap_addr.vci, - encapsulation); + _LOGD (LOGD_ADSL, "assigning address %d.%d.%d encapsulation %s", + priv->atm_index, addr.sap_addr.vpi, addr.sap_addr.vci, + encapsulation ? encapsulation : "(none)"); err = connect (priv->brfd, (struct sockaddr*) &addr, sizeof (addr)); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to set VPI/VCI (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to set VPI/VCI (%d)", errsv); goto error; } @@ -278,8 +281,8 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) be.encaps = is_llc ? BR2684_ENCAPS_LLC : BR2684_ENCAPS_VC; err = ioctl (priv->brfd, ATM_SETBACKEND, &be); if (err != 0) { - nm_log_err (LOGD_ADSL, "(%s): failed to attach VCC (%d)", - iface, errno); + errsv = errno; + _LOGE (LOGD_ADSL, "failed to attach VCC (%d)", errsv); goto error; } @@ -292,18 +295,17 @@ error: } static void -link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDeviceAdsl *device_adsl) +link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDeviceAdsl *self) { if (change_type == NM_PLATFORM_SIGNAL_REMOVED) { - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (device_adsl); - NMDevice *device = NM_DEVICE (device_adsl); + NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); /* This only gets called for PPPoE connections and "nas" interfaces */ if (priv->nas_ifindex >= 0 && ifindex == priv->nas_ifindex) { /* NAS device went away for some reason; kill the connection */ - nm_log_dbg (LOGD_ADSL, "(%s): NAS interface disappeared", - nm_device_get_iface (device)); + _LOGD (LOGD_ADSL, "NAS interface disappeared"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BR2684_FAILED); @@ -326,8 +328,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) g_assert (s_adsl); protocol = nm_setting_adsl_get_protocol (s_adsl); - nm_log_dbg (LOGD_ADSL, "(%s): using ADSL protocol '%s'", - nm_device_get_iface (device), protocol); + _LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol); if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) { @@ -348,7 +349,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) G_CALLBACK (link_changed_cb), self); - nm_log_dbg (LOGD_ADSL, "(%s): ATM setup successful", nm_device_get_iface (device)); + _LOGD (LOGD_ADSL, "ATM setup successful"); /* otherwise we're good for stage3 */ nm_platform_link_set_up (priv->nas_ifindex); @@ -357,10 +358,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) } else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) { /* PPPoA doesn't need anything special */ ret = NM_ACT_STAGE_RETURN_SUCCESS; - } else { - nm_log_warn (LOGD_ADSL, "(%s): unhandled ADSL protocol '%s'", - nm_device_get_iface (device), protocol); - } + } else + _LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol); done: return ret; @@ -410,7 +409,6 @@ act_stage3_ip4_config_start (NMDevice *device, NMActRequest *req; GError *err = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - const char *iface = nm_device_get_iface (device); const char *ppp_iface; req = nm_device_get_act_request (device); @@ -427,11 +425,10 @@ act_stage3_ip4_config_start (NMDevice *device, g_assert (priv->nas_ifname); ppp_iface = priv->nas_ifname; - nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoE on NAS interface %s", - iface, priv->nas_ifname); + _LOGD (LOGD_ADSL, "starting PPPoE on NAS interface %s", priv->nas_ifname); } else { - ppp_iface = iface; - nm_log_dbg (LOGD_ADSL, "(%s): starting PPPoA", iface); + ppp_iface = nm_device_get_iface (device); + _LOGD (LOGD_ADSL, "starting PPPoA"); } priv->ppp_manager = nm_ppp_manager_new (ppp_iface); @@ -444,7 +441,7 @@ act_stage3_ip4_config_start (NMDevice *device, self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { - nm_log_warn (LOGD_ADSL, "(%s): PPP failed to start: %s", iface, err->message); + _LOGW (LOGD_ADSL, "PPP failed to start: %s", err->message); g_error_free (err); g_object_unref (priv->ppp_manager); @@ -482,33 +479,19 @@ deactivate (NMDevice *device) priv->nas_ifindex = -1; g_free (priv->nas_ifname); priv->nas_ifname = NULL; - - /* Poke NMDevice to notice that our hw_address is no longer valid */ - nm_device_update_hw_address (NM_DEVICE (self)); } /**************************************************************/ -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) -{ - NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (device); - - return priv->nas_ifname ? ETH_ALEN : 0; -} - static gboolean carrier_update_cb (gpointer user_data) { NMDeviceAdsl *self = NM_DEVICE_ADSL (user_data); int carrier; char *path; - const char *iface; - - iface = nm_device_get_iface (NM_DEVICE (self)); path = g_strdup_printf ("/sys/class/atm/%s/carrier", - ASSERT_VALID_PATH_COMPONENT (iface)); + ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); carrier = (int) nm_platform_sysctl_get_int_checked (path, 10, 0, 1, -1); g_free (path); @@ -555,6 +538,7 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; + NMDeviceAdsl *self; NMDeviceAdslPrivate *priv; object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type, @@ -563,18 +547,16 @@ constructor (GType type, if (!object) return NULL; + self = NM_DEVICE_ADSL (object); priv = NM_DEVICE_ADSL_GET_PRIVATE (object); priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object))); if (priv->atm_index < 0) { - nm_log_err (LOGD_ADSL, "(%s): error reading ATM device index", - nm_device_get_iface (NM_DEVICE (object))); + _LOGE (LOGD_ADSL, "error reading ATM device index"); g_object_unref (object); return NULL; - } else { - nm_log_dbg (LOGD_ADSL, "(%s): ATM device index %d", - nm_device_get_iface (NM_DEVICE (object)), priv->atm_index); - } + } else + _LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index); /* Poll the carrier */ priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, object); @@ -629,7 +611,6 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; - parent_class->get_hw_address_length = get_hw_address_length; parent_class->act_stage2_config = act_stage2_config; parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; parent_class->deactivate = deactivate; diff --git a/src/devices/adsl/nm-device-adsl.h b/src/devices/adsl/nm-device-adsl.h index bbd0e63f..f21381c2 100644 --- a/src/devices/adsl/nm-device-adsl.h +++ b/src/devices/adsl/nm-device-adsl.h @@ -19,8 +19,8 @@ * Copyright (C) 2009 - 2011 Red Hat Inc. */ -#ifndef NM_DEVICE_ADSL_H -#define NM_DEVICE_ADSL_H +#ifndef __NETWORKMANAGER_DEVICE_ADSL_H__ +#define __NETWORKMANAGER_DEVICE_ADSL_H__ #include diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am index 639a1ad7..8ab561ac 100644 --- a/src/devices/bluetooth/Makefile.am +++ b/src/devices/bluetooth/Makefile.am @@ -5,26 +5,22 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/devices/wwan \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h +nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml dbus-binding-tool --prefix=nm_device_bt --mode=glib-server --output=$@ $< @@ -47,6 +43,8 @@ libnm_device_plugin_bluetooth_la_SOURCES = \ nm-bluez4-manager.h \ nm-bluez5-manager.c \ nm-bluez5-manager.h \ + nm-bt-error.h \ + nm-bt-error.c \ \ nm-device-bt.c \ nm-device-bt.h \ @@ -62,6 +60,16 @@ libnm_device_plugin_bluetooth_la_LIBADD = \ $(DBUS_LIBS) \ $(GUDEV_LIBS) +if WITH_BLUEZ5_DUN +AM_CPPFLAGS += $(BLUEZ5_CFLAGS) + +libnm_device_plugin_bluetooth_la_SOURCES += \ + nm-bluez5-dun.c \ + nm-bluez5-dun.h + +libnm_device_plugin_bluetooth_la_LIBADD += $(BLUEZ5_LIBS) +endif + CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = $(SYMBOL_VIS_FILE) diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in index 3145c52d..0a285fda 100644 --- a/src/devices/bluetooth/Makefile.in +++ b/src/devices/bluetooth/Makefile.in @@ -78,6 +78,12 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@WITH_BLUEZ5_DUN_TRUE@am__append_1 = $(BLUEZ5_CFLAGS) +@WITH_BLUEZ5_DUN_TRUE@am__append_2 = \ +@WITH_BLUEZ5_DUN_TRUE@ nm-bluez5-dun.c \ +@WITH_BLUEZ5_DUN_TRUE@ nm-bluez5-dun.h + +@WITH_BLUEZ5_DUN_TRUE@am__append_3 = $(BLUEZ5_LIBS) subdir = src/devices/bluetooth DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -131,14 +137,26 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = +@WITH_BLUEZ5_DUN_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libnm_device_plugin_bluetooth_la_DEPENDENCIES = \ $(top_builddir)/src/devices/wwan/libnm-wwan.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +am__libnm_device_plugin_bluetooth_la_SOURCES_DIST = \ + nm-bluez-manager.c nm-bluez-manager.h nm-bluez-common.h \ + nm-bluez-device.c nm-bluez-device.h nm-bluez4-adapter.c \ + nm-bluez4-adapter.h nm-bluez4-manager.c nm-bluez4-manager.h \ + nm-bluez5-manager.c nm-bluez5-manager.h nm-bt-error.h \ + nm-bt-error.c nm-device-bt.c nm-device-bt.h nm-bt-enum-types.h \ + nm-bt-enum-types.c nm-device-bt-glue.h nm-bluez5-dun.c \ + nm-bluez5-dun.h am__objects_1 = nm-bt-enum-types.lo am__objects_2 = $(am__objects_1) +@WITH_BLUEZ5_DUN_TRUE@am__objects_3 = nm-bluez5-dun.lo am_libnm_device_plugin_bluetooth_la_OBJECTS = nm-bluez-manager.lo \ nm-bluez-device.lo nm-bluez4-adapter.lo nm-bluez4-manager.lo \ - nm-bluez5-manager.lo nm-device-bt.lo $(am__objects_2) + nm-bluez5-manager.lo nm-bt-error.lo nm-device-bt.lo \ + $(am__objects_2) $(am__objects_3) libnm_device_plugin_bluetooth_la_OBJECTS = \ $(am_libnm_device_plugin_bluetooth_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -184,7 +202,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES) -DIST_SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES) +DIST_SOURCES = $(am__libnm_device_plugin_bluetooth_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -219,6 +237,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -342,6 +362,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -361,6 +382,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -387,7 +409,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -466,59 +488,35 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I${top_srcdir}/src \ - -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/settings \ - -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/devices/wwan \ - -I${top_builddir}/include \ - -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ +AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src \ + -I${top_srcdir}/src/devices -I${top_srcdir}/src/settings \ + -I${top_srcdir}/src/platform -I${top_srcdir}/src/devices/wwan \ + -I${top_srcdir}/include -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \ - -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) - + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(DBUS_CFLAGS) \ + $(am__append_1) GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM -nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h +nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h BUILT_SOURCES = $(GLIB_GENERATED) nm-device-bt-glue.h pkglib_LTLIBRARIES = libnm-device-plugin-bluetooth.la SYMBOL_VIS_FILE = $(srcdir)/exports.ver -libnm_device_plugin_bluetooth_la_SOURCES = \ - nm-bluez-manager.c \ - nm-bluez-manager.h \ - nm-bluez-common.h \ - nm-bluez-device.c \ - nm-bluez-device.h \ - nm-bluez4-adapter.c \ - nm-bluez4-adapter.h \ - nm-bluez4-manager.c \ - nm-bluez4-manager.h \ - nm-bluez5-manager.c \ - nm-bluez5-manager.h \ - \ - nm-device-bt.c \ - nm-device-bt.h \ - \ - $(BUILT_SOURCES) - +libnm_device_plugin_bluetooth_la_SOURCES = nm-bluez-manager.c \ + nm-bluez-manager.h nm-bluez-common.h nm-bluez-device.c \ + nm-bluez-device.h nm-bluez4-adapter.c nm-bluez4-adapter.h \ + nm-bluez4-manager.c nm-bluez4-manager.h nm-bluez5-manager.c \ + nm-bluez5-manager.h nm-bt-error.h nm-bt-error.c nm-device-bt.c \ + nm-device-bt.h $(BUILT_SOURCES) $(am__append_2) libnm_device_plugin_bluetooth_la_LDFLAGS = \ -module -avoid-version \ -Wl,--version-script=$(SYMBOL_VIS_FILE) -libnm_device_plugin_bluetooth_la_LIBADD = \ - $(top_builddir)/src/devices/wwan/libnm-wwan.la \ - $(DBUS_LIBS) \ - $(GUDEV_LIBS) - +libnm_device_plugin_bluetooth_la_LIBADD = \ + $(top_builddir)/src/devices/wwan/libnm-wwan.la $(DBUS_LIBS) \ + $(GUDEV_LIBS) $(am__append_3) CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = $(SYMBOL_VIS_FILE) all: $(BUILT_SOURCES) @@ -605,8 +603,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-adapter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-dun.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bt.Plo@am__quote@ .c.o: diff --git a/src/devices/bluetooth/exports.ver b/src/devices/bluetooth/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/bluetooth/exports.ver +++ b/src/devices/bluetooth/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index f80cfc2e..f0cab43b 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Red Hat, Inc. */ -#ifndef NM_BLUEZ_COMMON_H -#define NM_BLUEZ_COMMON_H +#ifndef __NETWORKMANAGER_BLUEZ_COMMON_H__ +#define __NETWORKMANAGER_BLUEZ_COMMON_H__ #include diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 4c448a37..fe1a97bb 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -19,22 +19,24 @@ * Copyright (C) 2013 Intel Corporation. */ +#include "config.h" + #include #include #include #include -#include -#include -#include "NetworkManager.h" -#include "nm-setting-bluetooth.h" +#include "nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-device.h" #include "nm-logging.h" -#include "nm-utils.h" #include "nm-settings-connection.h" +#include "NetworkManagerUtils.h" +#if WITH_BLUEZ5_DUN +#include "nm-bluez5-dun.h" +#endif G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT) @@ -55,19 +57,21 @@ typedef struct { gboolean usable; NMBluetoothCapabilities connection_bt_type; + char *adapter_address; char *address; - guint8 bin_address[ETH_ALEN]; char *name; guint32 capabilities; gboolean connected; - char *bt_iface; + char *b4_iface; +#if WITH_BLUEZ5_DUN + NMBluez5DunContext *b5_dun_context; +#endif NMConnectionProvider *provider; GSList *connections; NMConnection *pan_connection; - NMConnection *pan_connection_original; gboolean pan_connection_no_autocreate; } NMBluezDevicePrivate; @@ -156,9 +160,12 @@ nm_bluez_device_get_capabilities (NMBluezDevice *self) gboolean nm_bluez_device_get_connected (NMBluezDevice *self) { + NMBluezDevicePrivate *priv; + g_return_val_if_fail (NM_IS_BLUEZ_DEVICE (self), FALSE); - return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->connected; + priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); + return priv->connected; } static void @@ -168,7 +175,6 @@ pan_connection_check_create (NMBluezDevice *self) NMConnection *added; NMSetting *setting; char *uuid, *id; - GByteArray *bdaddr_array; GError *error = NULL; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); @@ -187,7 +193,7 @@ pan_connection_check_create (NMBluezDevice *self) /* create a new connection */ - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Setting: Connection */ uuid = nm_utils_uuid_generate (); @@ -202,29 +208,26 @@ pan_connection_check_create (NMBluezDevice *self) nm_connection_add_setting (connection, setting); /* Setting: Bluetooth */ - bdaddr_array = g_byte_array_sized_new (sizeof (priv->bin_address)); - g_byte_array_append (bdaddr_array, priv->bin_address, sizeof (priv->bin_address)); setting = nm_setting_bluetooth_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_BLUETOOTH_BDADDR, bdaddr_array, + NM_SETTING_BLUETOOTH_BDADDR, priv->address, NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, NULL); nm_connection_add_setting (connection, setting); - g_byte_array_free (bdaddr_array, TRUE); /* Setting: IPv4 */ setting = nm_setting_ip4_config_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_MAY_FAIL, FALSE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, NULL); nm_connection_add_setting (connection, setting); /* Setting: IPv6 */ setting = nm_setting_ip6_config_new (); g_object_set (G_OBJECT (setting), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); nm_connection_add_setting (connection, setting); @@ -240,9 +243,10 @@ pan_connection_check_create (NMBluezDevice *self) g_assert (connection_compatible (self, added)); g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT)); + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, TRUE); + priv->connections = g_slist_prepend (priv->connections, g_object_ref (added)); priv->pan_connection = added; - priv->pan_connection_original = connection; nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid); } else { nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %d / %s", @@ -250,8 +254,8 @@ pan_connection_check_create (NMBluezDevice *self) (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - g_object_unref (connection); } + g_object_unref (connection); g_free (id); g_free (uuid); @@ -264,13 +268,12 @@ check_emit_usable (NMBluezDevice *self) gboolean new_usable; /* only expect the supported capabilities set. */ - g_assert (priv->bluez_version != 4 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE )); - g_assert (priv->bluez_version != 5 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP )) == NM_BT_CAPABILITY_NONE )); + g_assert ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE ); new_usable = (priv->initialized && priv->capabilities && priv->name && ((priv->bluez_version == 4) || (priv->bluez_version == 5 && priv->adapter5 && priv->adapter_powered) ) && - priv->dbus_connection && priv->address); + priv->dbus_connection && priv->address && priv->adapter_address); if (!new_usable) goto END; @@ -302,7 +305,7 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection) NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); NMSettingBluetooth *s_bt; const char *bt_type; - const GByteArray *bdaddr; + const char *bdaddr; if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME)) return FALSE; @@ -311,14 +314,13 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection) if (!s_bt) return FALSE; - if (!priv->address) { - /* unless address is set, bin_address is not initialized. */ + if (!priv->address) return FALSE; - } + bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr || bdaddr->len != ETH_ALEN) + if (!bdaddr) return FALSE; - if (memcmp (bdaddr->data, priv->bin_address, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (bdaddr, -1, priv->address, -1)) return FALSE; bt_type = nm_setting_bluetooth_get_connection_type (s_bt); @@ -362,10 +364,8 @@ cp_connection_removed (NMConnectionProvider *provider, if (g_slist_find (priv->connections, connection)) { priv->connections = g_slist_remove (priv->connections, connection); - if (priv->pan_connection == connection) { + if (priv->pan_connection == connection) priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); - } g_object_unref (connection); check_emit_usable (self); } @@ -420,26 +420,37 @@ nm_bluez_device_disconnect (NMBluezDevice *self) { NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); GVariant *args = NULL; - const char *dbus_iface; + const char *dbus_iface = NULL; g_return_if_fail (priv->dbus_connection); - if (priv->bluez_version == 5) { - g_return_if_fail (priv->connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ5_NETWORK_INTERFACE; - } else if (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_DUN) { - /* Can't pass a NULL interface name through dbus to bluez, so just - * ignore the disconnect if the interface isn't known. - */ - if (!priv->bt_iface) - return; - - args = g_variant_new ("(s)", priv->bt_iface), - dbus_iface = BLUEZ4_SERIAL_INTERFACE; - } else { - g_return_if_fail (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ4_NETWORK_INTERFACE; - } + if (priv->connection_bt_type == NM_BT_CAPABILITY_DUN) { + if (priv->bluez_version == 4) { + /* Can't pass a NULL interface name through dbus to bluez, so just + * ignore the disconnect if the interface isn't known. + */ + if (!priv->b4_iface) + goto out; + args = g_variant_new ("(s)", priv->b4_iface), + dbus_iface = BLUEZ4_SERIAL_INTERFACE; + } else if (priv->bluez_version == 5) { +#if WITH_BLUEZ5_DUN + nm_bluez5_dun_cleanup (priv->b5_dun_context); +#else + g_assert_not_reached (); +#endif + priv->connected = FALSE; + goto out; + } + } else if (priv->connection_bt_type == NM_BT_CAPABILITY_NAP) { + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_NETWORK_INTERFACE; + else if (priv->bluez_version == 5) + dbus_iface = BLUEZ5_NETWORK_INTERFACE; + else + g_assert_not_reached (); + } else + g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, BLUEZ_SERVICE, @@ -454,6 +465,8 @@ nm_bluez_device_disconnect (NMBluezDevice *self) (GAsyncReadyCallback) bluez_disconnect_cb, g_object_ref (self)); +out: + g_clear_pointer (&priv->b4_iface, g_free); priv->connection_bt_type = NM_BT_CAPABILITY_NONE; } @@ -480,7 +493,7 @@ bluez_connect_cb (GDBusConnection *dbus_connection, g_simple_async_result_set_op_res_gpointer (result, g_strdup (device), g_free); - priv->bt_iface = device; + priv->b4_iface = device; g_variant_unref (variant); } @@ -489,6 +502,28 @@ bluez_connect_cb (GDBusConnection *dbus_connection, g_object_unref (result_object); } +#if WITH_BLUEZ5_DUN +static void +bluez5_dun_connect_cb (NMBluez5DunContext *context, + const char *device, + GError *error, + gpointer user_data) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + + if (error) { + g_simple_async_result_take_error (result, error); + } else { + g_simple_async_result_set_op_res_gpointer (result, + g_strdup (device), + g_free); + } + + g_simple_async_result_complete (result); + g_object_unref (result); +} +#endif + void nm_bluez_device_connect_async (NMBluezDevice *self, NMBluetoothCapabilities connection_bt_type, @@ -497,26 +532,39 @@ nm_bluez_device_connect_async (NMBluezDevice *self, { GSimpleAsyncResult *simple; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - const char *dbus_iface; - const char *connect_type = BLUETOOTH_CONNECT_NAP; + const char *dbus_iface = NULL; + const char *connect_type = NULL; g_return_if_fail (priv->capabilities & connection_bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP)); - if (priv->bluez_version == 5) { - g_return_if_fail (connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ5_NETWORK_INTERFACE; - } else if (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_DUN) { - dbus_iface = BLUEZ4_SERIAL_INTERFACE; - connect_type = BLUETOOTH_CONNECT_DUN; - } else { - g_return_if_fail (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_NAP); - dbus_iface = BLUEZ4_NETWORK_INTERFACE; - } - simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data, nm_bluez_device_connect_async); + priv->connection_bt_type = connection_bt_type; + + if (connection_bt_type == NM_BT_CAPABILITY_NAP) { + connect_type = BLUETOOTH_CONNECT_NAP; + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_NETWORK_INTERFACE; + else if (priv->bluez_version == 5) + dbus_iface = BLUEZ5_NETWORK_INTERFACE; + } else if (connection_bt_type == NM_BT_CAPABILITY_DUN) { + connect_type = BLUETOOTH_CONNECT_DUN; + if (priv->bluez_version == 4) + dbus_iface = BLUEZ4_SERIAL_INTERFACE; + else if (priv->bluez_version == 5) { +#if WITH_BLUEZ5_DUN + if (priv->b5_dun_context == NULL) + priv->b5_dun_context = nm_bluez5_dun_new (priv->adapter_address, priv->address); + nm_bluez5_dun_connect (priv->b5_dun_context, bluez5_dun_connect_cb, simple); +#else + g_assert_not_reached (); +#endif + return; + } + } else + g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, BLUEZ_SERVICE, @@ -530,8 +578,6 @@ nm_bluez_device_connect_async (NMBluezDevice *self, NULL, (GAsyncReadyCallback) bluez_connect_cb, simple); - - priv->connection_bt_type = connection_bt_type; } const char * @@ -539,6 +585,7 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, GAsyncResult *result, GError **error) { + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); GSimpleAsyncResult *simple; const char *device; @@ -553,13 +600,28 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, return NULL; device = (const char *) g_simple_async_result_get_op_res_gpointer (simple); + if (device && priv->bluez_version == 5) + priv->connected = TRUE; + return device; } /***********************************************************/ +static void +set_adapter_address (NMBluezDevice *self, const char *address) +{ + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); + + g_return_if_fail (address); + + if (priv->adapter_address) + g_free (priv->adapter_address); + priv->adapter_address = g_strdup (address); +} + static guint32 -convert_uuids_to_capabilities (const char **strings, int bluez_version) +convert_uuids_to_capabilities (const char **strings) { const char **iter; guint32 capabilities = 0; @@ -571,8 +633,7 @@ convert_uuids_to_capabilities (const char **strings, int bluez_version) if (parts && parts[0]) { switch (g_ascii_strtoull (parts[0], NULL, 16)) { case 0x1103: - if (bluez_version == 4) - capabilities |= NM_BT_CAPABILITY_DUN; + capabilities |= NM_BT_CAPABILITY_DUN; break; case 0x1116: capabilities |= NM_BT_CAPABILITY_NAP; @@ -593,7 +654,7 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids) guint32 uint_val; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - uint_val = convert_uuids_to_capabilities (uuids, priv->bluez_version); + uint_val = convert_uuids_to_capabilities (uuids); if (priv->capabilities != uint_val) { if (priv->capabilities) { /* changing (relevant) capabilities is not supported and ignored -- except setting initially */ @@ -613,13 +674,10 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids) /** * priv->address can only be set one to a certain (non NULL) value. Every later attempt * to reset it to another value will be ignored and a warning will be logged. - * - * When setting the address for the first time, we also set bin_address. **/ static void _set_property_address (NMBluezDevice *self, const char *addr) { - struct ether_addr *tmp; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); if (g_strcmp0 (priv->address, addr) == 0) @@ -635,15 +693,11 @@ _set_property_address (NMBluezDevice *self, const char *addr) return; } - tmp = ether_aton (addr); - if (!tmp) { - if (priv->address) - nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from '%s' to '%s' (invalid value)", priv->path, priv->address, addr); - else - nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from NULL to '%s' (invalid value)", priv->path, addr); + if (!nm_utils_hwaddr_valid (addr, ETH_ALEN)) { + nm_log_warn (LOGD_BT, "bluez[%s] cannot set address to '%s' (invalid value)", priv->path, addr); return; } - memcpy (priv->bin_address, tmp->ether_addr_octet, ETH_ALEN); + priv->address = g_strdup (addr); g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_ADDRESS); } @@ -752,6 +806,10 @@ adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) if (v) g_variant_unref (v); + v = g_dbus_proxy_get_cached_property (priv->adapter5, "Address"); + if (VARIANT_IS_OF_TYPE_STRING (v)) + set_adapter_address (self, g_variant_get_string (v, NULL)); + priv->initialized = TRUE; g_signal_emit (self, signals[INITIALIZED], 0, TRUE); @@ -957,7 +1015,10 @@ on_bus_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) /********************************************************************/ NMBluezDevice * -nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version) +nm_bluez_device_new (const char *path, + const char *adapter_address, + NMConnectionProvider *provider, + int bluez_version) { NMBluezDevice *self; NMBluezDevicePrivate *priv; @@ -978,8 +1039,10 @@ nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); priv->bluez_version = bluez_version; - priv->provider = provider; + 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, @@ -1037,14 +1100,19 @@ dispose (GObject *object) if (priv->pan_connection) { /* Check whether we want to remove the created connection. If so, we take a reference * and delete it at the end of dispose(). */ - if ( nm_settings_connection_get_unsaved (NM_SETTINGS_CONNECTION (priv->pan_connection)) - && nm_connection_compare (priv->pan_connection, priv->pan_connection_original, NM_SETTING_COMPARE_FLAG_EXACT)) + if (nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (priv->pan_connection))) to_delete = g_object_ref (priv->pan_connection); priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); } +#if WITH_BLUEZ5_DUN + if (priv->b5_dun_context) { + nm_bluez5_dun_free (priv->b5_dun_context); + priv->b5_dun_context = NULL; + } +#endif + 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); @@ -1073,9 +1141,10 @@ finalize (GObject *object) nm_log_dbg (LOGD_BT, "bluez[%s]: finalize NMBluezDevice", priv->path); g_free (priv->path); + g_free (priv->adapter_address); g_free (priv->address); g_free (priv->name); - g_free (priv->bt_iface); + g_free (priv->b4_iface); if (priv->proxy) g_signal_handlers_disconnect_by_data (priv->proxy, object); @@ -1148,51 +1217,45 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class) /* Properties */ g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_BLUEZ_DEVICE_PATH, - "DBus Path", - "DBus Path", + g_param_spec_string (NM_BLUEZ_DEVICE_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ADDRESS, - g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS, - "Address", - "Address", + g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_BLUEZ_DEVICE_NAME, - "Name", - "Name", + g_param_spec_string (NM_BLUEZ_DEVICE_NAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, - "Capabilities", - "Capabilities", - 0, G_MAXUINT, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_USABLE, - g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE, - "Usable", - "Usable", + g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONNECTED, - g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED, - "Connected", - "Connected", + g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[INITIALIZED] = g_signal_new ("initialized", diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h index 0bf7d898..92d99fa7 100644 --- a/src/devices/bluetooth/nm-bluez-device.h +++ b/src/devices/bluetooth/nm-bluez-device.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 - 2014 Red Hat, Inc. */ -#ifndef NM_BLUEZ_DEVICE_H -#define NM_BLUEZ_DEVICE_H +#ifndef __NETWORKMANAGER_BLUEZ_DEVICE_H__ +#define __NETWORKMANAGER_BLUEZ_DEVICE_H__ #include #include @@ -62,7 +62,10 @@ typedef struct { GType nm_bluez_device_get_type (void); -NMBluezDevice *nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version); +NMBluezDevice *nm_bluez_device_new (const char *path, + const char *adapter_address, + NMConnectionProvider *provider, + int bluez_version); const char *nm_bluez_device_get_path (NMBluezDevice *self); @@ -94,5 +97,5 @@ nm_bluez_device_connect_finish (NMBluezDevice *self, void nm_bluez_device_disconnect (NMBluezDevice *self); -#endif /* NM_BLUEZ_DEVICE_H */ +#endif /* __NETWORKMANAGER_BLUEZ_DEVICE_H__ */ diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 04ffb0a4..e176a4b4 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -62,20 +64,12 @@ static void check_bluez_and_try_setup (NMBluezManager *self); /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_BT - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ struct AsyncData { @@ -368,6 +362,18 @@ check_bluez_and_try_setup (NMBluezManager *self) async_data_pack (self)); } +static void +start (NMDeviceFactory *factory) +{ + check_bluez_and_try_setup (NM_BLUEZ_MANAGER (factory)); +} + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_BT; +} + /*********************************************************************/ static void @@ -390,16 +396,6 @@ dispose (GObject *object) priv->bluez_version = 0; } -static void -constructed (GObject *object) -{ - NMBluezManager *self = NM_BLUEZ_MANAGER (object); - - G_OBJECT_CLASS (nm_bluez_manager_parent_class)->constructed (object); - - check_bluez_and_try_setup (self); -} - static void nm_bluez_manager_init (NMBluezManager *self) { @@ -412,6 +408,8 @@ nm_bluez_manager_init (NMBluezManager *self) static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void @@ -423,6 +421,5 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass) /* virtual methods */ object_class->dispose = dispose; - object_class->constructed = constructed; } diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h index 68d6dbe5..8320b298 100644 --- a/src/devices/bluetooth/nm-bluez-manager.h +++ b/src/devices/bluetooth/nm-bluez-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_BLUEZ_MANAGER_H -#define NM_BLUEZ_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ_MANAGER_H__ #include #include @@ -40,5 +40,5 @@ typedef struct { GObjectClass parent; } NMBluezManagerClass; -#endif /* NM_BLUEZ_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c index ad1786f0..9d1cfe1f 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.c +++ b/src/devices/bluetooth/nm-bluez4-adapter.c @@ -18,10 +18,12 @@ * Copyright (C) 2009 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-bluez4-adapter.h" #include "nm-bluez-device.h" @@ -162,7 +164,7 @@ device_created (DBusGProxy *proxy, const char *path, gpointer user_data) NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self); NMBluezDevice *device; - device = nm_bluez_device_new (path, priv->provider, 4); + device = nm_bluez_device_new (path, priv->address, priv->provider, 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); @@ -371,19 +373,17 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class) /* Properties */ g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH, - "DBus Path", - "DBus Path", + g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ADDRESS, - g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS, - "Address", - "Address", + g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[INITIALIZED] = g_signal_new ("initialized", diff --git a/src/devices/bluetooth/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h index 454ca557..a6256412 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.h +++ b/src/devices/bluetooth/nm-bluez4-adapter.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 - 2012 Red Hat, Inc. */ -#ifndef NM_BLUEZ4_ADAPTER_H -#define NM_BLUEZ4_ADAPTER_H +#ifndef __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ +#define __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ #include #include @@ -65,5 +65,5 @@ gboolean nm_bluez4_adapter_get_initialized (NMBluez4Adapter *self); GSList *nm_bluez4_adapter_get_devices (NMBluez4Adapter *self); -#endif /* NM_BLUEZ4_ADAPTER_H */ +#endif /* __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c index 2660cbd9..23b13d32 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -19,6 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include diff --git a/src/devices/bluetooth/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h index 19b1c65a..13cfef93 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.h +++ b/src/devices/bluetooth/nm-bluez4-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#ifndef NM_BLUEZ4_MANAGER_H -#define NM_BLUEZ4_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ4_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ4_MANAGER_H__ #include #include @@ -58,5 +58,5 @@ NMBluez4Manager *nm_bluez4_manager_new (NMConnectionProvider *provider); void nm_bluez4_manager_query_devices (NMBluez4Manager *manager); -#endif /* NM_BLUEZ4_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ4_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c new file mode 100644 index 00000000..a97eaa77 --- /dev/null +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -0,0 +1,410 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-bluez5-dun.h" +#include "nm-bt-error.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" + +struct _NMBluez5DunContext { + bdaddr_t src; + bdaddr_t dst; + char *src_str; + char *dst_str; + int rfcomm_channel; + int rfcomm_fd; + int rfcomm_tty_fd; + int rfcomm_id; + NMBluez5DunFunc callback; + gpointer user_data; + sdp_session_t *sdp_session; + guint sdp_watch_id; +}; + +static void +dun_connect (NMBluez5DunContext *context) +{ + struct sockaddr_rc sa; + int devid, try = 30; + char tty[100]; + const int ttylen = sizeof (tty) - 1; + GError *error = NULL; + + struct rfcomm_dev_req req = { + .flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), + .dev_id = -1, + .channel = context->rfcomm_channel + }; + + context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (context->rfcomm_fd < 0) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to create RFCOMM socket: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + /* Connect to the remote device */ + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = 0; + memcpy (&sa.rc_bdaddr, &context->src, ETH_ALEN); + if (bind (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof(sa))) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to bind socket: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + sa.rc_channel = context->rfcomm_channel; + memcpy (&sa.rc_bdaddr, &context->dst, ETH_ALEN); + if (connect (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof (sa)) ) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to connect to remote device: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + + nm_log_dbg (LOGD_BT, "(%s): connected to %s on channel %d", + context->src_str, context->dst_str, context->rfcomm_channel); + + /* Create an RFCOMM kernel device for the DUN channel */ + memcpy (&req.src, &context->src, ETH_ALEN); + memcpy (&req.dst, &context->dst, ETH_ALEN); + devid = ioctl (context->rfcomm_fd, RFCOMMCREATEDEV, &req); + if (devid < 0) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to create rfcomm device: (%d) %s", + errsv, strerror (errsv)); + goto done; + } + context->rfcomm_id = devid; + + snprintf (tty, ttylen, "/dev/rfcomm%d", devid); + while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY)) < 0 && try--) { + if (try) { + g_usleep (100 * 1000); + continue; + } + + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to find rfcomm device: %s", + tty); + break; + } + +done: + context->callback (context, tty, error, context->user_data); +} + +static void +sdp_search_cleanup (NMBluez5DunContext *context) +{ + if (context->sdp_session) { + sdp_close (context->sdp_session); + context->sdp_session = NULL; + } + + if (context->sdp_watch_id) { + g_source_remove (context->sdp_watch_id); + context->sdp_watch_id = 0; + } +} + +static void +sdp_search_completed_cb (uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data) +{ + NMBluez5DunContext *context = user_data; + int scanned, seqlen = 0, bytesleft = size; + uint8_t dataType; + int channel = -1; + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished with type=%d status=%d", + context->src_str, context->dst_str, status, type); + + /* SDP response received */ + if (status || type != SDP_SVC_SEARCH_ATTR_RSP) { + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Did not get a Service Discovery response"); + context->callback (context, NULL, error, context->user_data); + goto done; + } + + scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP sequence type scanned=%d length=%d", + context->src_str, context->dst_str, scanned, seqlen); + + scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen); + if (!scanned || !seqlen) { + /* Short read or unknown sequence type */ + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Improper Service Discovery response"); + context->callback (context, NULL, error, context->user_data); + goto done; + } + + rsp += scanned; + bytesleft -= scanned; + do { + sdp_record_t *rec; + int recsize = 0; + sdp_list_t *protos; + + rec = sdp_extract_pdu (rsp, bytesleft, &recsize); + if (!rec) + break; + + if (!recsize) { + sdp_record_free (rec); + break; + } + + if (sdp_get_access_protos (rec, &protos) == 0) { + /* Extract the DUN channel number */ + channel = sdp_get_proto_port (protos, RFCOMM_UUID); + sdp_list_free (protos, NULL); + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP channel=%d", + context->src_str, context->dst_str, channel); + } + sdp_record_free (rec); + + scanned += recsize; + rsp += recsize; + bytesleft -= recsize; + } while ((scanned < (ssize_t) size) && (bytesleft > 0) && (channel < 0)); + +done: + if (channel != -1) { + context->rfcomm_channel = channel; + dun_connect (context); + } + + sdp_search_cleanup (context); +} + +static gboolean +sdp_search_process_cb (GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + NMBluez5DunContext *context = user_data; + + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search progressed with condition=%d", + context->src_str, context->dst_str, condition); + + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + GError *error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Service Discovery interrupted"); + context->callback (context, NULL, error, context->user_data); + sdp_search_cleanup (context); + return FALSE; + } + + if (sdp_process (context->sdp_session) < 0) { + nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished", + context->src_str, context->dst_str); + + /* Search finished successfully. */ + return FALSE; + } + + /* Search progressed successfully. */ + return TRUE; +} + +static gboolean +sdp_connect_watch (GIOChannel *channel, GIOCondition condition, gpointer user_data) +{ + NMBluez5DunContext *context = user_data; + sdp_list_t *search, *attrs; + uuid_t svclass; + uint16_t attr; + int fd, err, fd_err = 0; + socklen_t len = sizeof (fd_err); + GError *error = NULL; + + context->sdp_watch_id = 0; + + fd = g_io_channel_unix_get_fd (channel); + if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) { + nm_log_dbg (LOGD_BT, "(%s -> %s): getsockopt error=%d", + context->src_str, context->dst_str, errno); + err = errno; + } else { + nm_log_dbg (LOGD_BT, "(%s -> %s): SO_ERROR error=%d", + context->src_str, context->dst_str, fd_err); + err = fd_err; + } + + if (err != 0) { + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Error on Service Discovery socket: (%d) %s", + err, strerror (err)); + goto done; + } + + if (sdp_set_notify (context->sdp_session, sdp_search_completed_cb, context) < 0) { + /* Should not be reached, only can fail if we passed bad sdp_session. */ + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Could not request Service Discovery notification"); + goto done; + } + + sdp_uuid16_create (&svclass, DIALUP_NET_SVCLASS_ID); + search = sdp_list_append (NULL, &svclass); + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append (NULL, &attr); + + if (!sdp_service_search_attr_async (context->sdp_session, search, SDP_ATTR_REQ_INDIVIDUAL, attrs)) { + /* Set callback responsible for update the internal SDP transaction */ + context->sdp_watch_id = g_io_add_watch (channel, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + sdp_search_process_cb, + context); + } else { + err = sdp_get_error (context->sdp_session); + error = g_error_new (NM_BT_ERROR, + NM_BT_ERROR_DUN_CONNECT_FAILED, + "Error starting Service Discovery: (%d) %s", + err, strerror (err)); + } + + sdp_list_free (attrs, NULL); + sdp_list_free (search, NULL); + +done: + if (error) { + context->callback (context, NULL, error, context->user_data); + sdp_search_cleanup (context); + } + + return G_SOURCE_REMOVE; +} + +NMBluez5DunContext * +nm_bluez5_dun_new (const char *adapter, + const char *remote) + +{ + NMBluez5DunContext *context; + + context = g_slice_new0 (NMBluez5DunContext); + str2ba (adapter, &context->src); + str2ba (remote, &context->dst); + context->src_str = g_strdup (adapter); + context->dst_str = g_strdup (remote); + context->rfcomm_channel = -1; + context->rfcomm_id = -1; + context->rfcomm_fd = -1; + return context; +} + +void +nm_bluez5_dun_connect (NMBluez5DunContext *context, + NMBluez5DunFunc callback, + gpointer user_data) +{ + GIOChannel *channel; + + context->callback = callback; + context->user_data = user_data; + + if (context->rfcomm_channel != -1) { + nm_log_dbg (LOGD_BT, "(%s): channel number on device %s cached: %d", + context->src_str, context->dst_str, context->rfcomm_channel); + dun_connect (context); + return; + } + + nm_log_dbg (LOGD_BT, "(%s): starting channel number discovery for device %s", + context->src_str, context->dst_str); + + context->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING); + if (!context->sdp_session) { + GError *error; + int err = sdp_get_error (context->sdp_session); + + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, + "Failed to connect to the SDP server: (%d) %s", + err, strerror (err)); + context->callback (context, NULL, error, context->user_data); + return; + } + + channel = g_io_channel_unix_new (sdp_get_socket (context->sdp_session)); + context->sdp_watch_id = g_io_add_watch (channel, + G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + sdp_connect_watch, + context); + g_io_channel_unref (channel); +} + +/* Only clean up connection-related stuff to allow reconnect */ +void +nm_bluez5_dun_cleanup (NMBluez5DunContext *context) +{ + g_return_if_fail (context != NULL); + + sdp_search_cleanup (context); + + if (context->rfcomm_fd >= 0) { + if (context->rfcomm_id >= 0) { + struct rfcomm_dev_req req = { 0 }; + + req.dev_id = context->rfcomm_id; + ioctl (context->rfcomm_fd, RFCOMMRELEASEDEV, &req); + context->rfcomm_id = -1; + } + close (context->rfcomm_fd); + context->rfcomm_fd = -1; + } + + close (context->rfcomm_tty_fd); + context->rfcomm_tty_fd = -1; +} + +void +nm_bluez5_dun_free (NMBluez5DunContext *context) +{ + g_return_if_fail (context != NULL); + + nm_bluez5_dun_cleanup (context); + g_clear_pointer (&context->src_str, g_free); + g_clear_pointer (&context->dst_str, g_free); + g_slice_free (NMBluez5DunContext, context); +} diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h new file mode 100644 index 00000000..7e259725 --- /dev/null +++ b/src/devices/bluetooth/nm-bluez5-dun.h @@ -0,0 +1,46 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef _NM_BLUEZ5_UTILS_H_ +#define _NM_BLUEZ5_UTILS_H_ + +#include +#include + +typedef struct _NMBluez5DunContext NMBluez5DunContext; + +typedef void (*NMBluez5DunFunc) (NMBluez5DunContext *context, + const char *rfcomm_dev, + GError *error, + gpointer user_data); + +NMBluez5DunContext *nm_bluez5_dun_new (const char *adapter, + const char *remote); + +void nm_bluez5_dun_connect (NMBluez5DunContext *context, + NMBluez5DunFunc callback, gpointer user_data); + +/* Clean up connection resources */ +void nm_bluez5_dun_cleanup (NMBluez5DunContext *context); + +/* Clean up and dispose all resources */ +void nm_bluez5_dun_free (NMBluez5DunContext *context); + +#endif /* _NM_BLUEZ5_UTILS_H_ */ diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 63006b3a..b8568523 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -20,6 +20,8 @@ * Copyright (C) 2013 Intel Corporation. */ +#include "config.h" + #include #include #include @@ -143,7 +145,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, priv->provider, 5); + device = nm_bluez_device_new (path, NULL, priv->provider, 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); diff --git a/src/devices/bluetooth/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h index 79f347bc..8152976d 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.h +++ b/src/devices/bluetooth/nm-bluez5-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -#ifndef NM_BLUEZ5_MANAGER_H -#define NM_BLUEZ5_MANAGER_H +#ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__ +#define __NETWORKMANAGER_BLUEZ5_MANAGER_H__ #include #include @@ -58,5 +58,5 @@ NMBluez5Manager *nm_bluez5_manager_new (NMConnectionProvider *provider); void nm_bluez5_manager_query_devices (NMBluez5Manager *manager); -#endif /* NM_BLUEZ5_MANAGER_H */ +#endif /* __NETWORKMANAGER_BLUEZ5_MANAGER_H__ */ diff --git a/src/devices/bluetooth/nm-bt-enum-types.c b/src/devices/bluetooth/nm-bt-enum-types.c index 2595caeb..16741c9f 100644 --- a/src/devices/bluetooth/nm-bt-enum-types.c +++ b/src/devices/bluetooth/nm-bt-enum-types.c @@ -5,7 +5,7 @@ #include "nm-bt-enum-types.h" -#include "nm-device-bt.h" +#include "nm-bt-error.h" GType nm_bt_error_get_type (void) @@ -18,6 +18,7 @@ nm_bt_error_get_type (void) { NM_BT_ERROR_CONNECTION_NOT_BT, "NM_BT_ERROR_CONNECTION_NOT_BT", "ConnectionNotBt" }, { NM_BT_ERROR_CONNECTION_INVALID, "NM_BT_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, { NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "NM_BT_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, + { NM_BT_ERROR_DUN_CONNECT_FAILED, "NM_BT_ERROR_DUN_CONNECT_FAILED", "DunConnectFailed" }, { 0, NULL, NULL } }; GType g_define_type_id = diff --git a/src/devices/bluetooth/nm-bt-error.c b/src/devices/bluetooth/nm-bt-error.c new file mode 100644 index 00000000..e3b8e7f5 --- /dev/null +++ b/src/devices/bluetooth/nm-bt-error.c @@ -0,0 +1,35 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include "nm-bt-error.h" + +GQuark +nm_bt_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-bt-error"); + return quark; +} + + diff --git a/src/devices/bluetooth/nm-bt-error.h b/src/devices/bluetooth/nm-bt-error.h new file mode 100644 index 00000000..fa3a9570 --- /dev/null +++ b/src/devices/bluetooth/nm-bt-error.h @@ -0,0 +1,35 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef _NM_BLUEZ5_ERROR_H_ +#define _NM_BLUEZ5_ERROR_H_ + +typedef enum { + NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ + NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ + NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ + NM_BT_ERROR_DUN_CONNECT_FAILED, /*< nick=DunConnectFailed >*/ +} NMBtError; + +#define NM_BT_ERROR (nm_bt_error_quark ()) +GQuark nm_bt_error_quark (void); + +#endif /* _NM_BT_ERROR_H_ */ + diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 0bd2f17d..689f37c9 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -22,8 +22,6 @@ #include #include -#include -#include #include #include @@ -46,9 +44,13 @@ #include "NetworkManagerUtils.h" #include "nm-bt-enum-types.h" #include "nm-utils.h" +#include "nm-bt-error.h" +#include "nm-bt-enum-types.h" + +#define MM_DBUS_SERVICE "org.freedesktop.ModemManager1" -#define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_NEW_DBUS_SERVICE "org.freedesktop.ModemManager1" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBt); G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) @@ -63,7 +65,7 @@ typedef struct { NMBluezDevice *bt_device; - guint8 bdaddr[ETH_ALEN]; + char *bdaddr; char *name; guint32 capabilities; @@ -94,17 +96,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -#define NM_BT_ERROR (nm_bt_error_quark ()) - -static GQuark -nm_bt_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bt-error"); - return quark; -} - guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) { g_return_val_if_fail (NM_IS_DEVICE_BT (self), NM_BT_CAPABILITY_NONE); @@ -112,15 +103,6 @@ guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) return NM_DEVICE_BT_GET_PRIVATE (self)->capabilities; } -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) -{ - /* HW address is the Bluetooth HW address of the remote device */ - if (out_permanent) - *out_permanent = TRUE; /* the bdaddr of the remote device will never change */ - return ETH_ALEN; -} - static guint32 get_connection_bt_type (NMConnection *connection) { @@ -142,6 +124,12 @@ get_connection_bt_type (NMConnection *connection) return NM_BT_CAPABILITY_NONE; } +static guint32 +get_generic_capabilities (NMDevice *device) +{ + return NM_DEVICE_CAP_IS_NON_KERNEL; +} + static gboolean can_auto_connect (NMDevice *device, NMConnection *connection, @@ -167,7 +155,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingConnection *s_con; NMSettingBluetooth *s_bt; - const GByteArray *array; + const char *bdaddr; guint32 bt_type; if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection)) @@ -187,11 +175,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!(bt_type & priv->capabilities)) return FALSE; - array = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!array || (array->len != ETH_ALEN)) + bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); + if (!bdaddr) return FALSE; - - if (memcmp (priv->bdaddr, array->data, ETH_ALEN) != 0) + if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1)) return FALSE; return TRUE; @@ -225,14 +212,14 @@ complete_connection (NMDevice *device, { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingBluetooth *s_bt; - const GByteArray *setting_bdaddr; + const char *setting_bdaddr; const char *ctype; gboolean is_dun = FALSE, is_pan = FALSE; NMSettingGsm *s_gsm; NMSettingCdma *s_cdma; NMSettingSerial *s_serial; - NMSettingPPP *s_ppp; - const char *format = NULL, *preferred = NULL; + NMSettingPpp *s_ppp; + const char *fallback_prefix = NULL, *preferred = NULL; s_gsm = nm_connection_get_setting_gsm (connection); s_cdma = nm_connection_get_setting_cdma (connection); @@ -262,18 +249,24 @@ complete_connection (NMDevice *device, /* Make sure the device supports PAN */ if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "PAN required but Bluetooth device does not support NAP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("PAN requested, but Bluetooth device does not support NAP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } /* PAN can't use any DUN-related settings */ if (s_gsm || s_cdma || s_serial || s_ppp) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "PAN incompatible with GSM, CDMA, or serial settings"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("PAN connections cannot specify GSM, CDMA, or serial settings")); + g_prefix_error (error, "%s: ", + s_gsm ? NM_SETTING_GSM_SETTING_NAME : + s_cdma ? NM_SETTING_CDMA_SETTING_NAME : + s_serial ? NM_SETTING_SERIAL_SETTING_NAME : + NM_SETTING_PPP_SETTING_NAME); return FALSE; } @@ -281,23 +274,25 @@ complete_connection (NMDevice *device, NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, NULL); - format = _("PAN connection %d"); + fallback_prefix = _("PAN connection"); } else if (is_dun) { /* Make sure the device supports PAN */ if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "DUN required but Bluetooth device does not support DUN"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("DUN requested, but Bluetooth device does not support DUN")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } /* Need at least a GSM or a CDMA setting */ if (!s_gsm && !s_cdma) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "Setting requires DUN but no GSM or CDMA setting is present"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("DUN connection must include a GSM or CDMA setting")); + g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); return FALSE; } @@ -306,51 +301,46 @@ complete_connection (NMDevice *device, NULL); if (s_gsm) { - format = _("GSM connection %d"); + fallback_prefix = _("GSM connection"); if (!nm_setting_gsm_get_number (s_gsm)) g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - } else if (s_cdma) { - format = _("CDMA connection %d"); + } else { + fallback_prefix = _("CDMA connection"); if (!nm_setting_cdma_get_number (s_cdma)) g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL); - } else - format = _("DUN connection %d"); + } } else { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - "Unknown/unhandled Bluetooth connection type"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Unknown/unhandled Bluetooth connection type")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } nm_utils_complete_generic (connection, NM_SETTING_BLUETOOTH_SETTING_NAME, existing_connections, - format, preferred, + fallback_prefix, + NULL, is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */ setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); if (setting_bdaddr) { /* Make sure the setting BT Address (if any) matches the device's */ - if (memcmp (setting_bdaddr->data, priv->bdaddr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_bdaddr, -1, priv->bdaddr, -1)) { g_set_error_literal (error, - NM_SETTING_BLUETOOTH_ERROR, - NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, - NM_SETTING_BLUETOOTH_BDADDR); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); return FALSE; } } else { - GByteArray *bdaddr; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - /* Lock the connection to this device by default */ - if (memcmp (priv->bdaddr, null_mac, ETH_ALEN)) { - bdaddr = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bdaddr, priv->bdaddr, ETH_ALEN); - g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL); - g_byte_array_free (bdaddr, TRUE); - } + if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, NULL, ETH_ALEN)) + g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, priv->bdaddr, NULL); } return TRUE; @@ -437,7 +427,8 @@ modem_prepare_result (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDevice *device = NM_DEVICE (self); NMDeviceState state; state = nm_device_get_state (device); @@ -470,8 +461,7 @@ modem_prepare_result (NMModem *modem, * the SIM if the incorrect PIN continues to be used. */ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL); - nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN", - nm_device_get_iface (device)); + _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN"); } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); @@ -491,21 +481,20 @@ device_state_changed (NMDevice *device, } static void -modem_ip4_config_result (NMModem *self, +modem_ip4_config_result (NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { - nm_log_warn (LOGD_MB | LOGD_IP4 | LOGD_BT, - "(%s): retrieving IP4 configuration failed: (%d) %s", - nm_device_get_ip_iface (device), - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT, + "retrieving IP4 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); } else @@ -648,16 +637,14 @@ component_added (NMDevice *device, GObject *component) */ state = nm_device_get_state (NM_DEVICE (self)); if (state != NM_DEVICE_STATE_CONFIG) { - nm_log_warn (LOGD_BT | LOGD_MB, - "(%s): modem found but device not in correct state (%d)", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_state (NM_DEVICE (self))); + _LOGW (LOGD_BT | LOGD_MB, + "modem found but device not in correct state (%d)", + nm_device_get_state (NM_DEVICE (self))); return TRUE; } - nm_log_info (LOGD_BT | LOGD_MB, - "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) modem found.", - nm_device_get_iface (NM_DEVICE (self))); + _LOGI (LOGD_BT | LOGD_MB, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) modem found."); if (priv->modem) { g_warn_if_reached (); @@ -674,11 +661,6 @@ component_added (NMDevice *device, GObject *component) g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self); - /* In the old ModemManager the data port is known from the very beginning; - * while in the new ModemManager the data port is set afterwards when the bearer gets - * created */ - if (modem_data_port) - nm_device_set_ip_iface (NM_DEVICE (self), modem_data_port); g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self); /* Kick off the modem connection */ @@ -711,11 +693,9 @@ check_connect_continue (NMDeviceBt *self) if (!priv->connected || !priv->have_iface) return; - nm_log_info (LOGD_BT, "Activation (%s %s/bluetooth) Stage 2 of 5 (Device Configure) " - "successful. Will connect via %s.", - nm_device_get_iface (device), - nm_device_get_ip_iface (device), - dun ? "DUN" : (pan ? "PAN" : "unknown")); + _LOGI (LOGD_BT, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) successful. Will connect via %s.", + dun ? "DUN" : (pan ? "PAN" : "unknown")); /* Kill the connect timeout since we're connected now */ if (priv->timeout_id) { @@ -730,9 +710,8 @@ check_connect_continue (NMDeviceBt *self) /* Wait for ModemManager to find the modem */ priv->timeout_id = g_timeout_add_seconds (30, modem_find_timeout, self); - nm_log_info (LOGD_BT | LOGD_MB, "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " - "waiting for modem to appear.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT | LOGD_MB, + "Activation: (bluetooth) Stage 2 of 5 (Device Configure) waiting for modem to appear."); } else g_assert_not_reached (); } @@ -751,13 +730,14 @@ bluez_connect_cb (GObject *object, res, &error); if (!device) { - nm_log_warn (LOGD_BT, "Error connecting with bluez: %s", - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_BT, "Error connecting with bluez: %s", + error && error->message ? error->message : "(unknown)"); g_clear_error (&error); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); + g_object_unref (self); return; } @@ -768,12 +748,12 @@ bluez_connect_cb (GObject *object, nm_device_set_ip_iface (NM_DEVICE (self), device); } - nm_log_dbg (LOGD_BT, "(%s): connect request successful", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_BT, "connect request successful"); /* Stage 3 gets scheduled when Bluez says we're connected */ priv->have_iface = TRUE; check_connect_continue (self); + g_object_unref (self); } static void @@ -790,8 +770,7 @@ bluez_connected_changed (NMBluezDevice *bt_device, connected = nm_bluez_device_get_connected (bt_device); if (connected) { if (state == NM_DEVICE_STATE_CONFIG) { - nm_log_dbg (LOGD_BT, "(%s): connected to the device", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "connected to the device"); priv->connected = TRUE; check_connect_continue (self); @@ -802,13 +781,10 @@ bluez_connected_changed (NMBluezDevice *bt_device, /* Bluez says we're disconnected from the device. Suck. */ if (nm_device_is_activating (device)) { - nm_log_info (LOGD_BT, - "Activation (%s/bluetooth): bluetooth link disconnected.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT, "Activation: (bluetooth) bluetooth link disconnected."); fail = TRUE; } else if (state == NM_DEVICE_STATE_ACTIVATED) { - nm_log_info (LOGD_BT, "(%s): bluetooth link disconnected.", - nm_device_get_iface (device)); + _LOGI (LOGD_BT, "bluetooth link disconnected."); fail = TRUE; } @@ -824,8 +800,7 @@ bt_connect_timeout (gpointer user_data) { NMDeviceBt *self = NM_DEVICE_BT (user_data); - nm_log_dbg (LOGD_BT, "(%s): initial connection timed out", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_BT, "initial connection timed out"); NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0; nm_device_state_changed (NM_DEVICE (self), @@ -837,6 +812,7 @@ bt_connect_timeout (gpointer user_data) static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { + NMDeviceBt *self = NM_DEVICE_BT (device); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMConnection *connection; @@ -853,13 +829,12 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_FAILURE; } - nm_log_dbg (LOGD_BT, "(%s): requesting connection to the device", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "requesting connection to the device"); /* Connect to the BT device */ nm_bluez_device_connect_async (priv->bt_device, priv->bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP), - bluez_connect_cb, device); + bluez_connect_cb, g_object_ref (device)); if (priv->timeout_id) g_source_remove (priv->timeout_id); @@ -897,8 +872,7 @@ act_stage3_ip6_config_start (NMDevice *device, if (priv->bt_type == NM_BT_CAPABILITY_DUN) { ret = nm_modem_stage3_ip6_config_start (NM_DEVICE_BT_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_bt_parent_class), + nm_device_get_act_request (device), reason); } else ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip6_config_start (device, out_config, reason); @@ -979,8 +953,7 @@ handle_availability_change (NMDeviceBt *self, state = nm_device_get_state (device); if (state < NM_DEVICE_STATE_UNAVAILABLE) { - nm_log_dbg (LOGD_BT, "(%s): availability blocked by UNMANAGED state", - nm_device_get_iface (device)); + _LOGD (LOGD_BT, "availability blocked by UNMANAGED state"); return; } @@ -990,7 +963,7 @@ handle_availability_change (NMDeviceBt *self, if (available) { if (state != NM_DEVICE_STATE_UNAVAILABLE) - nm_log_warn (LOGD_CORE | LOGD_BT, "not in expected unavailable state!"); + _LOGW (LOGD_CORE | LOGD_BT, "not in expected unavailable state!"); nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, @@ -1011,9 +984,8 @@ set_mm_running (NMDeviceBt *self, gboolean running) if (priv->mm_running == running) return; - nm_log_dbg (LOGD_BT, "(%s): ModemManager now %s", - nm_device_get_iface (NM_DEVICE (self)), - running ? "available" : "unavailable"); + _LOGD (LOGD_BT, "ModemManager now %s", + running ? "available" : "unavailable"); old_available = nm_device_is_available (NM_DEVICE (self)); priv->mm_running = running; @@ -1038,11 +1010,7 @@ mm_name_owner_changed (NMDBusManager *dbus_mgr, gboolean new_owner_good; /* Can't handle the signal if its not from the modem service */ - if ( strcmp (MM_OLD_DBUS_SERVICE, name) != 0 -#if WITH_MODEM_MANAGER_1 - && strcmp (MM_NEW_DBUS_SERVICE, name) != 0 -#endif - ) + if (strcmp (MM_DBUS_SERVICE, name) != 0) return; old_owner_good = (old_owner && strlen (old_owner)); @@ -1096,11 +1064,7 @@ nm_device_bt_init (NMDeviceBt *self) self); /* Initial check to see if ModemManager is running */ - mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_OLD_DBUS_SERVICE); -#if WITH_MODEM_MANAGER_1 - if (!mm_running) - mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_NEW_DBUS_SERVICE); -#endif + mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE); set_mm_running (self, mm_running); } @@ -1108,15 +1072,13 @@ static void constructed (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - const guint8 *my_hwaddr; - guint my_hwaddr_len = 0; + const char *my_hwaddr; G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); - my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object), &my_hwaddr_len); + my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object)); g_assert (my_hwaddr); - g_assert_cmpint (my_hwaddr_len, ==, ETH_ALEN); - memcpy (priv->bdaddr, my_hwaddr, ETH_ALEN); + priv->bdaddr = g_strdup (my_hwaddr); /* Watch for BT device property changes */ g_signal_connect (priv->bt_device, "notify::" NM_BLUEZ_DEVICE_CONNECTED, @@ -1203,6 +1165,7 @@ finalize (GObject *object) g_free (priv->rfcomm_iface); g_free (priv->name); + g_free (priv->bdaddr); G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); } @@ -1221,7 +1184,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; - device_class->get_hw_address_length = get_hw_address_length; + device_class->get_generic_capabilities = get_generic_capabilities; device_class->can_auto_connect = can_auto_connect; device_class->deactivate = deactivate; device_class->act_stage2_config = act_stage2_config; @@ -1238,27 +1201,24 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_BT_NAME, - g_param_spec_string (NM_DEVICE_BT_NAME, - "Bluetooth device name", - "Bluetooth device name", + g_param_spec_string (NM_DEVICE_BT_NAME, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, - "Bluetooth device capabilities", - "Bluetooth device capabilities", + g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, "", "", NM_BT_CAPABILITY_NONE, G_MAXUINT, NM_BT_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BT_DEVICE, - g_param_spec_object (NM_DEVICE_BT_DEVICE, - "NMBluezDevice object for the Device", - "NMBluezDevice object for the Device", + g_param_spec_object (NM_DEVICE_BT_DEVICE, "", "", NM_TYPE_BLUEZ_DEVICE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[PPP_STATS] = @@ -1273,6 +1233,4 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bt_object_info); - - dbus_g_error_domain_register (NM_BT_ERROR, NULL, NM_TYPE_BT_ERROR); } diff --git a/src/devices/bluetooth/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h index 83732bc0..c1e95d91 100644 --- a/src/devices/bluetooth/nm-device-bt.h +++ b/src/devices/bluetooth/nm-device-bt.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Red Hat, Inc. */ -#ifndef NM_DEVICE_BT_H -#define NM_DEVICE_BT_H +#ifndef __NETWORKMANAGER_DEVICE_BT_H__ +#define __NETWORKMANAGER_DEVICE_BT_H__ #include #include "nm-bluez-device.h" @@ -34,12 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT)) #define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass)) -typedef enum { - NM_BT_ERROR_CONNECTION_NOT_BT = 0, /*< nick=ConnectionNotBt >*/ - NM_BT_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBtError; - #define NM_DEVICE_BT_NAME "name" #define NM_DEVICE_BT_CAPABILITIES "bt-capabilities" #define NM_DEVICE_BT_DEVICE "bt-device" @@ -71,4 +65,4 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device, G_END_DECLS -#endif /* NM_DEVICE_BT_H */ +#endif /* __NETWORKMANAGER_DEVICE_BT_H__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 6f8caeb4..9d9fe426 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -23,30 +23,30 @@ #include #include -#include #include #include #include "gsystem-local-alloc.h" #include "nm-device-bond.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-platform.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-bond-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBond); G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) #define NM_DEVICE_BOND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BOND, NMDeviceBondPrivate)) -#define NM_BOND_ERROR (nm_bond_error_quark ()) - typedef struct { int dummy; } NMDeviceBondPrivate; @@ -60,17 +60,6 @@ enum { /******************************************************************/ -static GQuark -nm_bond_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bond-error"); - return quark; -} - -/******************************************************************/ - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -110,7 +99,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; /* Bond connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; @@ -126,17 +115,14 @@ complete_connection (NMDevice *device, const GSList *existing_connections, GError **error) { - NMSettingBond *s_bond, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; + NMSettingBond *s_bond; nm_utils_complete_generic (connection, NM_SETTING_BOND_SETTING_NAME, existing_connections, - _("Bond connection %d"), NULL, + _("Bond connection"), + "bond", TRUE); s_bond = nm_connection_get_setting_bond (connection); @@ -145,34 +131,6 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_bond)); } - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_bond_get_interface_name (s_bond)) { - name = g_strdup_printf ("bond%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing bond connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_bond (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_bond_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_bond), NM_SETTING_BOND_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - return TRUE; } @@ -181,14 +139,13 @@ complete_connection (NMDevice *device, static gboolean set_bond_attr (NMDevice *device, const char *attr, const char *value) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean ret; int ifindex = nm_device_get_ifindex (device); ret = nm_platform_master_set_option (ifindex, attr, value); - if (!ret) { - nm_log_warn (LOGD_HW, "(%s): failed to set bonding attribute " - "'%s' to '%s'", nm_device_get_ip_iface (device), attr, value); - } + if (!ret) + _LOGW (LOGD_HW, "failed to set bonding attribute '%s' to '%s'", attr, value); return ret; } @@ -209,14 +166,12 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingBond *s_bond = nm_connection_get_setting_bond (connection); - const char *ifname = nm_device_get_iface (device); int ifindex = nm_device_get_ifindex (device); const char **options; if (!s_bond) { s_bond = (NMSettingBond *) nm_setting_bond_new (); nm_connection_add_setting (connection, (NMSetting *) s_bond); - g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, ifname, NULL); } /* Read bond options from sysfs and update the Bond setting to match */ @@ -243,6 +198,19 @@ update_connection (NMDevice *device, NMConnection *connection) } } +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, nm_device_get_iface (self), + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BOND_SETTING_NAME, + NULL); + return TRUE; +} + static void set_arp_targets (NMDevice *device, const char *value, @@ -380,6 +348,10 @@ apply_bonding_config (NMDevice *device) set_simple_option (device, "xmit_hash_policy", s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY); set_simple_option (device, "resend_igmp", s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP); + if ( g_strcmp0 (mode, "4") == 0 + || g_strcmp0 (mode, "802.3ad") == 0) + set_simple_option (device, "lacp_rate", s_bond, NM_SETTING_BOND_OPTION_LACP_RATE); + return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -410,8 +382,8 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean success = TRUE, no_firmware = FALSE; - const char *iface = nm_device_get_ip_iface (device); const char *slave_iface = nm_device_get_ip_iface (slave); nm_device_master_check_slave_physical_port (device, slave, LOGD_BOND); @@ -425,9 +397,9 @@ enslave_slave (NMDevice *device, if (!success) return FALSE; - nm_log_info (LOGD_BOND, "(%s): enslaved bond slave %s", iface, slave_iface); + _LOGI (LOGD_BOND, "enslaved bond slave %s", slave_iface); } else - nm_log_info (LOGD_BOND, "(%s): bond slave %s was enslaved", iface, slave_iface); + _LOGI (LOGD_BOND, "bond slave %s was enslaved", slave_iface); g_object_notify (G_OBJECT (device), NM_DEVICE_BOND_SLAVES); return TRUE; @@ -438,6 +410,7 @@ release_slave (NMDevice *device, NMDevice *slave, gboolean configure) { + NMDeviceBond *self = NM_DEVICE_BOND (device); gboolean success = TRUE, no_firmware = FALSE; if (configure) { @@ -445,17 +418,14 @@ release_slave (NMDevice *device, nm_device_get_ip_ifindex (slave)); if (success) { - nm_log_info (LOGD_BOND, "(%s): released bond slave %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BOND, "released bond slave %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_warn (LOGD_BOND, "(%s): failed to release bond slave %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGW (LOGD_BOND, "failed to release bond slave %s", + nm_device_get_ip_iface (slave)); } } else { - nm_log_info (LOGD_BOND, "(%s): bond slave %s was released", - nm_device_get_ip_iface (device), + _LOGI (LOGD_BOND, "bond slave %s was released", nm_device_get_ip_iface (slave)); } @@ -467,10 +437,8 @@ release_slave (NMDevice *device, * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released slave. */ - if (!nm_device_bring_up (slave, TRUE, &no_firmware)) { - nm_log_warn (LOGD_BOND, "(%s): released bond slave could not be brought up.", - nm_device_get_iface (slave)); - } + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) + _LOGW (LOGD_BOND, "released bond slave could not be brought up."); } return success; @@ -478,57 +446,6 @@ release_slave (NMDevice *device, /******************************************************************/ -NMDevice * -nm_device_bond_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_DRIVER, "bonding", - NM_DEVICE_TYPE_DESC, "Bond", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -NMDevice * -nm_device_bond_new_for_connection (NMConnection *connection) -{ - const char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - if ( !nm_platform_bond_add (iface) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_BOND, "(%s): failed to create bonding master interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bonding", - NM_DEVICE_TYPE_DESC, "Bond", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_bond_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_BOND, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - static void nm_device_bond_init (NMDeviceBond * self) { @@ -579,7 +496,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->connection_type = NM_SETTING_BOND_SETTING_NAME; /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; @@ -590,6 +506,7 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; @@ -598,15 +515,69 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BOND_SLAVES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bond_object_info); +} + +/*************************************************************/ + +#define NM_TYPE_BOND_FACTORY (nm_bond_factory_get_type ()) +#define NM_BOND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BOND_FACTORY, NMBondFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_BOND) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_DRIVER, "bonding", + NM_DEVICE_TYPE_DESC, "Bond", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NM_DEVICE_IS_MASTER, TRUE, + NULL); + } + return NULL; +} + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + const char *iface; + + if (!nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + return NULL; + + iface = nm_connection_get_interface_name (connection); + g_return_val_if_fail (iface != NULL, NULL); - dbus_g_error_domain_register (NM_BOND_ERROR, NULL, NM_TYPE_BOND_ERROR); + if ( !nm_platform_bond_add (iface) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_BOND, "(%s): failed to create bonding master interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BOND, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bonding", + NM_DEVICE_TYPE_DESC, "Bond", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BOND, + NM_DEVICE_IS_MASTER, TRUE, + NULL); } + +DEFINE_DEVICE_FACTORY_INTERNAL(BOND, Bond, bond, + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-bond.h b/src/devices/nm-device-bond.h index f4683ad8..17217a57 100644 --- a/src/devices/nm-device-bond.h +++ b/src/devices/nm-device-bond.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_BOND_H -#define NM_DEVICE_BOND_H +#ifndef __NETWORKMANAGER_DEVICE_BOND_H__ +#define __NETWORKMANAGER_DEVICE_BOND_H__ #include @@ -34,29 +34,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BOND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BOND)) #define NM_DEVICE_BOND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BOND, NMDeviceBondClass)) -typedef enum { - NM_BOND_ERROR_CONNECTION_NOT_BOND = 0, /*< nick=ConnectionNotBond >*/ - NM_BOND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBondError; - #define NM_DEVICE_BOND_SLAVES "slaves" -typedef struct { - NMDevice parent; -} NMDeviceBond; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceBondClass; - +typedef NMDevice NMDeviceBond; +typedef NMDeviceClass NMDeviceBondClass; GType nm_device_bond_get_type (void); -NMDevice *nm_device_bond_new (NMPlatformLink *platform_device); -NMDevice *nm_device_bond_new_for_connection (NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_BOND_H */ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index edc41838..a70cfd95 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -23,29 +23,29 @@ #include #include -#include #include #include "gsystem-local-alloc.h" #include "nm-device-bridge.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-enum-types.h" #include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-bridge-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceBridge); G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) #define NM_DEVICE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgePrivate)) -#define NM_BRIDGE_ERROR (nm_bridge_error_quark ()) - typedef struct { int dummy; } NMDeviceBridgePrivate; @@ -59,17 +59,6 @@ enum { /******************************************************************/ -static GQuark -nm_bridge_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-bridge-error"); - return quark; -} - -/******************************************************************/ - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -100,7 +89,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) { const char *iface; NMSettingBridge *s_bridge; - const GByteArray *mac_address; + const char *mac_address; if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -110,19 +99,16 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; /* Bridge connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (!iface || strcmp (nm_device_get_iface (device), iface)) return FALSE; mac_address = nm_setting_bridge_get_mac_address (s_bridge); if (mac_address) { - guint hw_len; - const guint8 *hw_addr; + const char *hw_addr; - hw_addr = nm_device_get_hw_address (device, &hw_len); - if ( !hw_addr - || hw_len != mac_address->len - || memcmp (mac_address->data, hw_addr, hw_len) != 0) + hw_addr = nm_device_get_hw_address (device); + if (!hw_addr || !nm_utils_hwaddr_matches (hw_addr, -1, mac_address, -1)) return FALSE; } @@ -136,17 +122,14 @@ complete_connection (NMDevice *device, const GSList *existing_connections, GError **error) { - NMSettingBridge *s_bridge, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; + NMSettingBridge *s_bridge; nm_utils_complete_generic (connection, NM_SETTING_BRIDGE_SETTING_NAME, existing_connections, - _("Bridge connection %d"), NULL, + _("Bridge connection"), + "bridge", TRUE); s_bridge = nm_connection_get_setting_bridge (connection); @@ -155,34 +138,6 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_bridge)); } - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_bridge_get_interface_name (s_bridge)) { - name = g_strdup_printf ("br%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing bridge connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_bridge (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_BRIDGE_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_bridge_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_bridge), NM_SETTING_BRIDGE_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - return TRUE; } @@ -292,15 +247,14 @@ commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) static void update_connection (NMDevice *device, NMConnection *connection) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); NMSettingBridge *s_bridge = nm_connection_get_setting_bridge (connection); - const char *ifname = nm_device_get_iface (device); int ifindex = nm_device_get_ifindex (device); const Option *option; if (!s_bridge) { s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); nm_connection_add_setting (connection, (NMSetting *) s_bridge); - g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, ifname, NULL); } for (option = master_options; option->name; option++) { @@ -315,34 +269,27 @@ update_connection (NMDevice *device, NMConnection *connection) value /= 100; g_object_set (s_bridge, option->name, value, NULL); - } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to read bridge setting '%s'", - nm_device_get_iface (device), option->sysname); - } + } else + _LOGW (LOGD_BRIDGE, "failed to read bridge setting '%s'", option->sysname); } } -/** - * nm_bridge_update_slave_connection: - * @slave: the slave #NMDevice, is *not* necessarily a bridge interface - * @connection: the #NMConnection to update with the bridge port settings - * - * Reads bridge port configuration and updates @connection with those - * properties. - * - * Returns: %TRUE if the port configuration was read and @connection updated, - * %FALSE if not. - */ -gboolean -nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) +static gboolean +master_update_slave_connection (NMDevice *device, + NMDevice *slave, + NMConnection *connection, + GError **error) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + NMSettingConnection *s_con; NMSettingBridgePort *s_port; - int ifindex = nm_device_get_ifindex (slave); + int ifindex_slave = nm_device_get_ifindex (slave); + const char *iface = nm_device_get_iface (device); const Option *option; - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (ifindex_slave > 0, FALSE); + s_con = nm_connection_get_setting_connection (connection); s_port = nm_connection_get_setting_bridge_port (connection); if (!s_port) { s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); @@ -350,7 +297,7 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) } for (option = slave_options; option->name; option++) { - gs_free char *str = nm_platform_slave_get_option (ifindex, option->sysname); + gs_free char *str = nm_platform_slave_get_option (ifindex_slave, option->sysname); int value; if (str) { @@ -361,12 +308,14 @@ nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection) value /= 100; g_object_set (s_port, option->name, value, NULL); - } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to read bridge port setting '%s'", - nm_device_get_iface (slave), option->sysname); - } + } else + _LOGW (LOGD_BRIDGE, "failed to read bridge port setting '%s'", option->sysname); } + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, + NULL); return TRUE; } @@ -393,19 +342,19 @@ enslave_slave (NMDevice *device, NMConnection *connection, gboolean configure) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + if (configure) { if (!nm_platform_link_enslave (nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave))) return FALSE; commit_slave_options (slave, nm_connection_get_setting_bridge_port (connection)); - nm_log_info (LOGD_BRIDGE, "(%s): attached bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "attached bridge port %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_info (LOGD_BRIDGE, "(%s): bridge port %s was attached", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "bridge port %s was attached", + nm_device_get_ip_iface (slave)); } g_object_notify (G_OBJECT (device), NM_DEVICE_BRIDGE_SLAVES); @@ -418,6 +367,7 @@ release_slave (NMDevice *device, NMDevice *slave, gboolean configure) { + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); gboolean success = TRUE; if (configure) { @@ -425,18 +375,15 @@ release_slave (NMDevice *device, nm_device_get_ip_ifindex (slave)); if (success) { - nm_log_info (LOGD_BRIDGE, "(%s): detached bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "detached bridge port %s", + nm_device_get_ip_iface (slave)); } else { - nm_log_warn (LOGD_BRIDGE, "(%s): failed to detach bridge port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGW (LOGD_BRIDGE, "failed to detach bridge port %s", + nm_device_get_ip_iface (slave)); } } else { - nm_log_info (LOGD_BRIDGE, "(%s): bridge port %s was detached", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); + _LOGI (LOGD_BRIDGE, "bridge port %s was detached", + nm_device_get_ip_iface (slave)); } g_object_notify (G_OBJECT (device), NM_DEVICE_BRIDGE_SLAVES); @@ -445,66 +392,6 @@ release_slave (NMDevice *device, /******************************************************************/ -NMDevice * -nm_device_bridge_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_DRIVER, "bridge", - NM_DEVICE_TYPE_DESC, "Bridge", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -NMDevice * -nm_device_bridge_new_for_connection (NMConnection *connection) -{ - const char *iface; - NMSettingBridge *s_bridge; - const GByteArray *mac_address; - - g_return_val_if_fail (connection != NULL, NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - s_bridge = nm_connection_get_setting_bridge (connection); - g_return_val_if_fail (s_bridge, NULL); - - mac_address = nm_setting_bridge_get_mac_address (s_bridge); - - if ( !nm_platform_bridge_add (iface, - mac_address ? mac_address->data : NULL, - mac_address ? mac_address->len : 0) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "bridge", - NM_DEVICE_TYPE_DESC, "Bridge", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_bridge_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_BRIDGE, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - static void nm_device_bridge_init (NMDeviceBridge * self) { @@ -518,7 +405,6 @@ get_property (GObject *object, guint prop_id, GSList *list, *iter; switch (prop_id) { - break; case PROP_SLAVES: slaves = g_ptr_array_new (); list = nm_device_master_get_slaves (NM_DEVICE (object)); @@ -555,7 +441,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->connection_type = NM_SETTING_BRIDGE_SETTING_NAME; /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; @@ -566,6 +451,7 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->enslave_slave = enslave_slave; @@ -574,15 +460,85 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, - "Slaves", - "Slaves", + g_param_spec_boxed (NM_DEVICE_BRIDGE_SLAVES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_bridge_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_BRIDGE_ERROR, NULL, NM_TYPE_BRIDGE_ERROR); +#define NM_TYPE_BRIDGE_FACTORY (nm_bridge_factory_get_type ()) +#define NM_BRIDGE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BRIDGE_FACTORY, NMBridgeFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_BRIDGE) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_DRIVER, "bridge", + NM_DEVICE_TYPE_DESC, "Bridge", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, + NM_DEVICE_IS_MASTER, TRUE, + NULL); + } + return NULL; } + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + const char *iface; + NMSettingBridge *s_bridge; + const char *mac_address_str; + guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; + + if (!nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (connection != NULL, NULL); + + iface = nm_connection_get_interface_name (connection); + g_return_val_if_fail (iface != NULL, NULL); + + s_bridge = nm_connection_get_setting_bridge (connection); + g_return_val_if_fail (s_bridge, NULL); + + mac_address_str = nm_setting_bridge_get_mac_address (s_bridge); + if (mac_address_str) { + if (!nm_utils_hwaddr_aton (mac_address_str, mac_address, ETH_ALEN)) + mac_address_str = NULL; + } + + if ( !nm_platform_bridge_add (iface, + mac_address_str ? mac_address : NULL, + mac_address_str ? ETH_ALEN : 0) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_BRIDGE, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "bridge", + NM_DEVICE_TYPE_DESC, "Bridge", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_BRIDGE, + NM_DEVICE_IS_MASTER, TRUE, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL(BRIDGE, Bridge, bridge, + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index 4194f5a4..c11a2c40 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_BRIDGE_H -#define NM_DEVICE_BRIDGE_H +#ifndef __NETWORKMANAGER_DEVICE_BRIDGE_H__ +#define __NETWORKMANAGER_DEVICE_BRIDGE_H__ #include @@ -34,31 +34,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BRIDGE)) #define NM_DEVICE_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BRIDGE, NMDeviceBridgeClass)) -typedef enum { - NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE = 0, /*< nick=ConnectionNotBridge >*/ - NM_BRIDGE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMBridgeError; - #define NM_DEVICE_BRIDGE_SLAVES "slaves" -typedef struct { - NMDevice parent; -} NMDeviceBridge; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceBridgeClass; - +typedef NMDevice NMDeviceBridge; +typedef NMDeviceClass NMDeviceBridgeClass; GType nm_device_bridge_get_type (void); -NMDevice *nm_device_bridge_new (NMPlatformLink *platform_device); -NMDevice *nm_device_bridge_new_for_connection (NMConnection *connection); - -gboolean nm_bridge_update_slave_connection (NMDevice *slave, NMConnection *connection); - G_END_DECLS #endif /* NM_DEVICE_BRIDGE_H */ diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c new file mode 100644 index 00000000..585f6a0e --- /dev/null +++ b/src/devices/nm-device-ethernet-utils.c @@ -0,0 +1,55 @@ +/* -*- 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include "nm-device-ethernet-utils.h" + +char * +nm_device_ethernet_utils_get_default_wired_name (const GSList *connections) +{ + const GSList *iter; + char *cname = NULL; + int i = 0; + + /* Find the next available unique connection name */ + while (!cname && (i++ < 10000)) { + char *temp; + gboolean found = FALSE; + + 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; + g_free (temp); + break; + } + } + + if (found == FALSE) + cname = temp; + } + + return cname; +} + diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h new file mode 100644 index 00000000..5848f7e6 --- /dev/null +++ b/src/devices/nm-device-ethernet-utils.h @@ -0,0 +1,26 @@ +/* -*- 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ +#define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ + +#include + +char *nm_device_ethernet_utils_get_default_wired_name (const GSList *connections); + +#endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index f4a90c74..ac408d3d 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -20,6 +20,7 @@ */ #include "config.h" + #include #include #include @@ -30,9 +31,7 @@ #include #include #include -#include #include -#include #include @@ -44,22 +43,23 @@ #include "nm-supplicant-manager.h" #include "nm-supplicant-interface.h" #include "nm-supplicant-config.h" -#include "nm-setting-connection.h" -#include "nm-setting-wired.h" -#include "nm-setting-8021x.h" -#include "nm-setting-pppoe.h" -#include "nm-setting-bond.h" #include "ppp-manager/nm-ppp-manager.h" #include "nm-logging.h" -#include "nm-utils.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" #include "nm-platform.h" #include "nm-dcb.h" #include "nm-settings-connection.h" +#include "nm-config.h" +#include "nm-device-ethernet-utils.h" +#include "nm-connection-provider.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-ethernet-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceEthernet); G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) @@ -69,8 +69,6 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) #define PPPOE_RECONNECT_DELAY 7 -#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ()) - static NMSetting *device_get_setting (NMDevice *device, GType setting_type); typedef struct Supplicant { @@ -101,8 +99,8 @@ typedef enum { } DcbWait; typedef struct { - guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ - guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ + char * perm_hw_addr; /* Permanent MAC address */ + char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */ guint32 speed; @@ -138,15 +136,6 @@ enum { }; -static GQuark -nm_ethernet_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-ethernet-error"); - return quark; -} - static char * get_link_basename (const char *parent_path, const char *name, GError **error) { @@ -167,7 +156,6 @@ static void _update_s390_subchannels (NMDeviceEthernet *self) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const char *iface; GUdevClient *client; GUdevDevice *dev; GUdevDevice *parent = NULL; @@ -176,17 +164,16 @@ _update_s390_subchannels (NMDeviceEthernet *self) GDir *dir; GError *error = NULL; - iface = nm_device_get_iface (NM_DEVICE (self)); - client = g_udev_client_new (subsystems); if (!client) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to initialize GUdev client", iface); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to initialize GUdev client"); return; } - dev = g_udev_client_query_by_subsystem_and_name (client, "net", iface); + dev = g_udev_client_query_by_subsystem_and_name (client, "net", + nm_device_get_iface (NM_DEVICE (self))); if (!dev) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to find device with udev", iface); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to find device with udev"); goto out; } @@ -203,9 +190,8 @@ _update_s390_subchannels (NMDeviceEthernet *self) parent_path = g_udev_device_get_sysfs_path (parent); dir = g_dir_open (parent_path, 0, &error); if (!dir) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): failed to open directory '%s': %s", - iface, parent_path, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to open directory '%s': %s", + parent_path, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); goto out; } @@ -228,12 +214,12 @@ _update_s390_subchannels (NMDeviceEthernet *self) if (value && *value) g_hash_table_insert (priv->s390_options, g_strdup (item), g_strdup (value)); else - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): error reading %s", iface, path); + _LOGW (LOGD_DEVICE | LOGD_HW, "error reading %s", path); g_free (path); g_free (value); } if (error) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, "(%s): %s", iface, error->message); + _LOGW (LOGD_DEVICE | LOGD_HW, "%s", error->message); g_clear_error (&error); } } @@ -253,9 +239,8 @@ _update_s390_subchannels (NMDeviceEthernet *self) priv->subchannels = g_strdup (priv->subchan1); driver = nm_device_get_driver (NM_DEVICE (self)); - nm_log_info (LOGD_DEVICE | LOGD_HW, - "(%s): found s390 '%s' subchannels [%s]", - iface, driver ? driver : "(unknown driver)", priv->subchannels); + _LOGI (LOGD_DEVICE | LOGD_HW, "found s390 '%s' subchannels [%s]", + driver ? driver : "(unknown driver)", priv->subchannels); out: if (parent) @@ -271,25 +256,22 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; - NMDevice *self; - int ifindex; object = G_OBJECT_CLASS (nm_device_ethernet_parent_class)->constructor (type, n_construct_params, construct_params); if (object) { - self = NM_DEVICE (object); - ifindex = nm_device_get_ifindex (self); +#ifndef G_DISABLE_ASSERT + int ifindex = nm_device_get_ifindex (NM_DEVICE (object)); + NMLinkType link_type = nm_platform_link_get_type (ifindex); - g_assert ( nm_platform_link_get_type (ifindex) == NM_LINK_TYPE_ETHERNET - || nm_platform_link_get_type (ifindex) == NM_LINK_TYPE_VETH); - - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); + g_assert ( link_type == NM_LINK_TYPE_ETHERNET + || link_type == NM_LINK_TYPE_VETH + || link_type == NM_LINK_TYPE_NONE); +#endif /* s390 stuff */ - _update_s390_subchannels (NM_DEVICE_ETHERNET (self)); + _update_s390_subchannels (NM_DEVICE_ETHERNET (object)); } return object; @@ -328,18 +310,6 @@ nm_device_ethernet_init (NMDeviceEthernet *self) priv->s390_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } -NMDevice * -nm_device_ethernet_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Ethernet", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, - NULL); -} - static void update_permanent_hw_address (NMDevice *dev) { @@ -347,12 +317,14 @@ update_permanent_hw_address (NMDevice *dev) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); struct ifreq req; struct ethtool_perm_addr *epaddr = NULL; - int fd, ret; - const guint8 *mac; + int fd, ret, errsv; + const char *mac; + + g_return_if_fail (priv->perm_hw_addr == NULL); fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); + _LOGW (LOGD_HW, "couldn't open control socket."); return; } @@ -367,21 +339,18 @@ update_permanent_hw_address (NMDevice *dev) errno = 0; ret = ioctl (fd, SIOCETHTOOL, &req); - if ((ret < 0) || !nm_ethernet_address_is_valid ((struct ether_addr *) epaddr->data)) { - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", - nm_device_get_iface (dev), errno); + errsv = errno; + if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) { + _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)", errsv); /* Fall back to current address */ - mac = nm_device_get_hw_address (dev, NULL); + mac = nm_device_get_hw_address (dev); if (mac) - memcpy (epaddr->data, mac, ETH_ALEN); + nm_utils_hwaddr_aton (mac, epaddr->data, ETH_ALEN); else memset (epaddr->data, 0, ETH_ALEN); } - if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { - memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN); - g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); - } + priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN); g_free (epaddr); close (fd); @@ -392,32 +361,25 @@ update_initial_hw_address (NMDevice *dev) { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - char *mac_str; - const guint8 *mac; /* This sets initial MAC address from current MAC address. It should only * be called from NMDevice constructor() to really get the initial address. */ - mac = nm_device_get_hw_address (dev, NULL); - if (mac) - memcpy (priv->initial_hw_addr, mac, ETH_ALEN); - - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev)); + + _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr); } static guint32 -get_generic_capabilities (NMDevice *dev) +get_generic_capabilities (NMDevice *device) { - if (nm_platform_link_supports_carrier_detect (nm_device_get_ifindex (dev))) + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + + if (nm_platform_link_supports_carrier_detect (nm_device_get_ifindex (device))) return NM_DEVICE_CAP_CARRIER_DETECT; else { - nm_log_info (LOGD_HW, - "(%s): driver '%s' does not support carrier detection.", - nm_device_get_iface (dev), - nm_device_get_driver (dev)); + _LOGI (LOGD_HW, "driver '%s' does not support carrier detection.", + nm_device_get_driver (device)); return NM_DEVICE_CAP_NONE; } } @@ -426,7 +388,7 @@ static gboolean match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const GPtrArray *subchans; + const char * const *subchans; int i; *try_mac = TRUE; @@ -440,8 +402,8 @@ match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_m return FALSE; /* Make sure each subchannel in the connection is a subchannel of this device */ - for (i = 0; i < subchans->len; i++) { - const char *candidate = g_ptr_array_index (subchans, i); + for (i = 0; subchans[i]; i++) { + const char *candidate = subchans[i]; if ( (priv->subchan1 && !strcmp (priv->subchan1, candidate)) || (priv->subchan2 && !strcmp (priv->subchan2, candidate)) @@ -476,29 +438,27 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; if (s_wired) { - const GByteArray *mac; + const char *mac; gboolean try_mac = TRUE; - const GSList *mac_blacklist, *mac_blacklist_iter; + const char * const *mac_blacklist; + int i; if (!match_subchans (self, s_wired, &try_mac)) return FALSE; mac = nm_setting_wired_get_mac_address (s_wired); - if (try_mac && mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) + if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1)) return FALSE; /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { g_warn_if_reached (); return FALSE; } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1)) return FALSE; } } @@ -588,14 +548,15 @@ wired_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDevice *dev = NM_DEVICE (self); g_return_if_fail (req == nm_device_get_act_request (dev)); g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); g_return_if_fail (nm_act_request_get_connection (req) == connection); if (error) { - nm_log_warn (LOGD_ETHER, "%s", error->message); + _LOGW (LOGD_ETHER, "%s", error->message); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); @@ -637,16 +598,14 @@ link_timeout_cb (gpointer user_data) if (!setting_name) goto time_out; - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): disconnected during authentication," - " asking for new key.", - nm_device_get_iface (dev)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) disconnected during authentication, asking for new key."); supplicant_interface_release (self); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wired_secrets_cb, self); @@ -654,8 +613,7 @@ link_timeout_cb (gpointer user_data) return FALSE; time_out: - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "(%s): link timed out.", nm_device_get_iface (dev)); + _LOGW (LOGD_DEVICE | LOGD_ETHER, "link timed out."); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); return FALSE; @@ -677,7 +635,7 @@ build_supplicant_config (NMDeviceEthernet *self) security = nm_connection_get_setting_802_1x (connection); if (!nm_supplicant_config_add_setting_8021x (config, security, con_uuid, TRUE)) { - nm_log_warn (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); + _LOGW (LOGD_DEVICE, "Couldn't add 802.1X security setting to supplicant config."); g_object_unref (config); config = NULL; } @@ -702,11 +660,9 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (new_state == old_state) return; - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "(%s): supplicant interface state: %s -> %s", - nm_device_get_iface (device), - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, "supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string (old_state), + nm_supplicant_interface_state_to_string (new_state)); devstate = nm_device_get_state (device); @@ -718,15 +674,12 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, g_object_unref (config); if (!success) { - nm_log_err (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): couldn't send security " - "configuration to the supplicant.", - nm_device_get_iface (device)); + _LOGE (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) couldn't send security configuration to the supplicant."); } } else { - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): couldn't build security configuration.", - nm_device_get_iface (device)); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) couldn't build security configuration."); } if (!success) { @@ -743,9 +696,8 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, * schedule the next activation stage. */ if (devstate == NM_DEVICE_STATE_CONFIG) { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.", - nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) Stage 2 of 5 (Device Configure) successful."); nm_device_activate_schedule_stage3_ip_config_start (device); } break; @@ -794,9 +746,9 @@ supplicant_iface_connection_error_cb (NMSupplicantInterface *iface, NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); guint id; - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): association request to the supplicant failed: %s - %s", - nm_device_get_iface (NM_DEVICE (self)), name, message); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) association request to the supplicant failed: %s - %s", + name, message); if (priv->supplicant.iface_con_error_cb_id) g_source_remove (priv->supplicant.iface_con_error_cb_id); @@ -826,16 +778,15 @@ handle_auth_or_fail (NMDeviceEthernet *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (new_secrets) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); - } else { - nm_log_info (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - } + } else + _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -848,19 +799,16 @@ supplicant_connection_timeout_cb (gpointer user_data) NMDevice *device = NM_DEVICE (self); NMActRequest *req; NMConnection *connection; - const char *iface; guint64 timestamp = 0; gboolean new_secrets = TRUE; priv->supplicant.con_timeout_id = 0; - iface = nm_device_get_iface (device); - /* Authentication failed; either driver problems, the encryption key is * wrong, the passwords or certificates were wrong or the Ethernet switch's * port is not configured for 802.1x. */ - nm_log_warn (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): association took too long.", iface); + _LOGW (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) association took too long."); supplicant_interface_release (self); req = nm_device_get_act_request (device); @@ -876,10 +824,9 @@ supplicant_connection_timeout_cb (gpointer user_data) if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) new_secrets = !timestamp; - if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): asking for new secrets", iface); - } else + if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) + _LOGW (LOGD_DEVICE | LOGD_ETHER, "Activation: (ethernet) asking for new secrets"); + else nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); return FALSE; @@ -889,16 +836,14 @@ static gboolean supplicant_interface_init (NMDeviceEthernet *self) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); - const char *iface; - - iface = nm_device_get_iface (NM_DEVICE (self)); /* Create supplicant interface */ - priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, iface, FALSE); + priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, + nm_device_get_iface (NM_DEVICE (self)), + FALSE); if (!priv->supplicant.iface) { - nm_log_err (LOGD_DEVICE | LOGD_ETHER, - "Couldn't initialize supplicant interface for %s.", - iface); + _LOGE (LOGD_DEVICE | LOGD_ETHER, + "Couldn't initialize supplicant interface"); supplicant_interface_release (self); return FALSE; } @@ -924,13 +869,12 @@ supplicant_interface_init (NMDeviceEthernet *self) static gboolean pppoe_reconnect_delay (gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); priv->pppoe_wait_id = 0; - nm_log_info (LOGD_DEVICE, "(%s) PPPoE reconnect delay complete, resuming connection...", - nm_device_get_iface (device)); - nm_device_activate_schedule_stage2_device_config (device); + _LOGI (LOGD_DEVICE, "PPPoE reconnect delay complete, resuming connection..."); + nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self)); return FALSE; } @@ -941,7 +885,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMActRequest *req; NMSettingWired *s_wired; - const GByteArray *cloned_mac; + const char *cloned_mac; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -955,8 +899,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, cloned_mac->data, "set", LOGD_ETHER); + if (cloned_mac) + nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_ETHER); } /* If we're re-activating a PPPoE connection a short while after @@ -968,8 +912,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) gint32 delay = nm_utils_get_monotonic_timestamp_s () - priv->last_pppoe_time; if (delay < PPPOE_RECONNECT_DELAY && device_get_setting (dev, NM_TYPE_SETTING_PPPOE)) { - nm_log_info (LOGD_DEVICE, "(%s) delaying PPPoE reconnect for %d seconds to ensure peer is ready...", - nm_device_get_iface (dev), delay); + _LOGI (LOGD_DEVICE, "delaying PPPoE reconnect for %d seconds to ensure peer is ready...", + delay); g_assert (!priv->pppoe_wait_id); priv->pppoe_wait_id = g_timeout_add_seconds (delay, pppoe_reconnect_delay, @@ -990,14 +934,13 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) NMConnection *connection; NMSetting8021x *security; const char *setting_name; - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; connection = nm_device_get_connection (NM_DEVICE (self)); g_assert (connection); security = nm_connection_get_setting_802_1x (connection); if (!security) { - nm_log_err (LOGD_DEVICE, "Invalid or missing 802.1X security"); + _LOGE (LOGD_DEVICE, "Invalid or missing 802.1X security"); *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; return ret; } @@ -1005,24 +948,22 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) if (!priv->supplicant.mgr) priv->supplicant.mgr = nm_supplicant_manager_get (); - iface = nm_device_get_iface (NM_DEVICE (self)); - /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self)); - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): connection '%s' has security, but secrets are required.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' has security, but secrets are required.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, req, FALSE); if (ret != NM_ACT_STAGE_RETURN_POSTPONE) *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } else { - nm_log_info (LOGD_DEVICE | LOGD_ETHER, - "Activation (%s/wired): connection '%s' requires no security. No secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_ETHER, + "Activation: (ethernet) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id (connection)); if (supplicant_interface_init (self)) ret = NM_ACT_STAGE_RETURN_POSTPONE; @@ -1073,7 +1014,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMConnection *connection; - NMSettingPPPOE *s_pppoe; + NMSettingPppoe *s_pppoe; NMActRequest *req; GError *err = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; @@ -1097,8 +1038,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas self); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else { - nm_log_warn (LOGD_DEVICE, "(%s): PPPoE failed to start: %s", - nm_device_get_iface (NM_DEVICE (self)), err->message); + _LOGW (LOGD_DEVICE, "PPPoE failed to start: %s", err->message); g_error_free (err); g_object_unref (priv->ppp_manager); @@ -1139,17 +1079,16 @@ static void dcb_state (NMDevice *device, gboolean timeout); static gboolean dcb_carrier_timeout (gpointer user_data) { + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (user_data); - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); g_return_val_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG, G_SOURCE_REMOVE); priv->dcb_timeout_id = 0; if (priv->dcb_wait != DCB_WAIT_CARRIER_POSTCONFIG_DOWN) { - nm_log_warn (LOGD_DCB, - "(%s): DCB: timed out waiting for carrier (step %d)", - nm_device_get_iface (device), - priv->dcb_wait); + _LOGW (LOGD_DCB, "DCB: timed out waiting for carrier (step %d)", + priv->dcb_wait); } dcb_state (device, TRUE); return G_SOURCE_REMOVE; @@ -1158,19 +1097,18 @@ dcb_carrier_timeout (gpointer user_data) static gboolean dcb_configure (NMDevice *device) { + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingDcb *s_dcb; - const char *iface = nm_device_get_iface (device); GError *error = NULL; dcb_timeout_cleanup (device); s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB); g_assert (s_dcb); - if (!nm_dcb_setup (iface, s_dcb, &error)) { - nm_log_warn (LOGD_DCB, - "Activation (%s/wired) failed to enable DCB/FCoE: %s", - iface, error->message); + if (!nm_dcb_setup (nm_device_get_iface (device), s_dcb, &error)) { + _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", + error->message); g_clear_error (&error); return FALSE; } @@ -1178,7 +1116,7 @@ dcb_configure (NMDevice *device) /* Pause again just in case the device takes the carrier down when * setting specific DCB attributes. */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (postconfig down)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (postconfig down)"); priv->dcb_wait = DCB_WAIT_CARRIER_POSTCONFIG_DOWN; priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); return TRUE; @@ -1187,15 +1125,14 @@ dcb_configure (NMDevice *device) static gboolean dcb_enable (NMDevice *device) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); GError *error = NULL; dcb_timeout_cleanup (device); - if (!nm_dcb_enable (iface, TRUE, &error)) { - nm_log_warn (LOGD_DCB, - "Activation (%s/wired) failed to enable DCB/FCoE: %s", - iface, error->message); + if (!nm_dcb_enable (nm_device_get_iface (device), TRUE, &error)) { + _LOGW (LOGD_DCB, "Activation: (ethernet) failed to enable DCB/FCoE: %s", + error->message); g_clear_error (&error); return FALSE; } @@ -1207,7 +1144,7 @@ dcb_enable (NMDevice *device) * is down. But NM might get the carrier-down signal long after calling * "dcbtool dcb on", so we have to first wait for the carrier to go down. */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preconfig down)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (preconfig down)"); priv->dcb_wait = DCB_WAIT_CARRIER_PRECONFIG_DOWN; priv->dcb_timeout_id = g_timeout_add_seconds (3, dcb_carrier_timeout, device); return TRUE; @@ -1216,25 +1153,25 @@ dcb_enable (NMDevice *device) static void dcb_state (NMDevice *device, gboolean timeout) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); - const char *iface = nm_device_get_iface (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); gboolean carrier; g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); carrier = nm_platform_link_is_connected (nm_device_get_ifindex (device)); - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() wait %d carrier %d timeout %d", iface, priv->dcb_wait, carrier, timeout); + _LOGD (LOGD_DCB, "dcb_state() wait %d carrier %d timeout %d", priv->dcb_wait, carrier, timeout); switch (priv->dcb_wait) { case DCB_WAIT_CARRIER_PREENABLE_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() enabling DCB", iface); + _LOGD (LOGD_DCB, "dcb_state() enabling DCB"); dcb_timeout_cleanup (device); if (!dcb_enable (device)) { dcb_carrier_cleanup (device); nm_device_state_changed (device, - NM_ACT_STAGE_RETURN_FAILURE, + NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); } } @@ -1245,20 +1182,20 @@ dcb_state (NMDevice *device, gboolean timeout) if (!carrier) { /* Wait for the carrier to come back up */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preconfig up)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (preconfig up)"); priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); break; } - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() preconfig down falling through", iface); + _LOGD (LOGD_DCB, "dcb_state() preconfig down falling through"); /* carrier never went down? fall through */ case DCB_WAIT_CARRIER_PRECONFIG_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() preconfig up configuring DCB", iface); + _LOGD (LOGD_DCB, "dcb_state() preconfig up configuring DCB"); dcb_timeout_cleanup (device); if (!dcb_configure (device)) { dcb_carrier_cleanup (device); nm_device_state_changed (device, - NM_ACT_STAGE_RETURN_FAILURE, + NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED); } } @@ -1269,15 +1206,15 @@ dcb_state (NMDevice *device, gboolean timeout) if (!carrier) { /* Wait for the carrier to come back up */ - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (postconfig up)", iface); + _LOGD (LOGD_DCB, "waiting for carrier (postconfig up)"); priv->dcb_timeout_id = g_timeout_add_seconds (5, dcb_carrier_timeout, device); break; } - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() postconfig down falling through", iface); + _LOGD (LOGD_DCB, "dcb_state() postconfig down falling through"); /* carrier never went down? fall through */ case DCB_WAIT_CARRIER_POSTCONFIG_UP: if (timeout || carrier) { - nm_log_dbg (LOGD_DCB, "(%s): dcb_state() postconfig up starting IP", iface); + _LOGD (LOGD_DCB, "dcb_state() postconfig up starting IP"); dcb_timeout_cleanup (device); dcb_carrier_cleanup (device); priv->dcb_wait = DCB_WAIT_UNKNOWN; @@ -1292,12 +1229,13 @@ dcb_state (NMDevice *device, gboolean timeout) static void dcb_carrier_changed (NMDevice *device, GParamSpec *pspec, gpointer unused) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_CONFIG); if (priv->dcb_timeout_id) { - nm_log_dbg (LOGD_DCB, "(%s): carrier_changed() calling dcb_state()", nm_device_get_iface (device)); + _LOGD (LOGD_DCB, "carrier_changed() calling dcb_state()"); dcb_state (device, FALSE); } } @@ -1307,7 +1245,8 @@ dcb_carrier_changed (NMDevice *device, GParamSpec *pspec, gpointer unused) static NMActStageReturn act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMSettingConnection *s_con; const char *connection_type; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; @@ -1331,7 +1270,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) security = (NMSetting8021x *) device_get_setting (device, NM_TYPE_SETTING_802_1X); if (security) { /* FIXME: for now 802.1x is mutually exclusive with DCB */ - return nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device), reason); + return nm_8021x_stage2_config (self, reason); } } @@ -1345,8 +1284,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_FAILURE; } } else { - nm_log_dbg (LOGD_DCB, "(%s): waiting for carrier (preenable up)", - nm_device_get_iface (device)); + _LOGD (LOGD_DCB, "waiting for carrier (preenable up)"); priv->dcb_wait = DCB_WAIT_CARRIER_PREENABLE_UP; priv->dcb_timeout_id = g_timeout_add_seconds (4, dcb_carrier_timeout, device); } @@ -1403,7 +1341,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) /* MTU override */ mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static void @@ -1442,9 +1380,8 @@ deactivate (NMDevice *device) s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB); if (s_dcb) { if (!nm_dcb_cleanup (nm_device_get_iface (device), &error)) { - nm_log_warn (LOGD_DEVICE | LOGD_HW, - "(%s) failed to disable DCB/FCoE: %s", - nm_device_get_iface (device), error->message); + _LOGW (LOGD_DEVICE | LOGD_HW, "failed to disable DCB/FCoE: %s", + error->message); g_clear_error (&error); } } @@ -1454,7 +1391,8 @@ deactivate (NMDevice *device) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->last_pppoe_time = nm_utils_get_monotonic_timestamp_s (); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER); } static gboolean @@ -1466,8 +1404,8 @@ complete_connection (NMDevice *device, { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingWired *s_wired; - NMSettingPPPOE *s_pppoe; - const GByteArray *setting_mac; + NMSettingPppoe *s_pppoe; + const char *setting_mac; s_pppoe = nm_connection_get_setting_pppoe (connection); @@ -1483,7 +1421,8 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME, existing_connections, - s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"), + NULL, + s_pppoe ? _("PPPoE connection") : _("Wired connection"), NULL, s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ @@ -1496,29 +1435,66 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) { g_set_error_literal (error, - NM_SETTING_WIRED_ERROR, - NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRED_MAC_ADDRESS); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - - /* Lock the connection to this device by default */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); - g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) { + g_object_set (G_OBJECT (s_wired), + NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, + NULL); } } return TRUE; } +static NMConnection * +new_default_connection (NMDevice *self) +{ + NMConnection *connection; + const GSList *connections; + NMSetting *setting; + const char *hw_address; + char *defname, *uuid; + + if (!nm_config_get_ethernet_can_auto_default (nm_config_get (), self)) + return NULL; + + hw_address = nm_device_get_hw_address (self); + if (!hw_address) + return NULL; + + connection = nm_simple_connection_new (); + 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); + uuid = nm_utils_uuid_generate (); + g_object_set (setting, + NM_SETTING_CONNECTION_ID, defname, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), + NULL); + g_free (uuid); + g_free (defname); + + /* Lock the connection to the device */ + setting = nm_setting_wired_new (); + g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, hw_address, NULL); + nm_connection_add_setting (connection, setting); + + return connection; +} + static gboolean spec_match_list (NMDevice *device, const GSList *specs) { @@ -1535,11 +1511,8 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); - guint maclen; - const guint8 *mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + const char *mac = nm_device_get_hw_address (device); const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; - GByteArray *array; GHashTableIter iter; gpointer key, value; @@ -1551,37 +1524,29 @@ update_connection (NMDevice *device, NMConnection *connection) /* If the device reports a permanent address, use that for the MAC address * and the current MAC, if different, is the cloned MAC. */ - if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, priv->perm_hw_addr, ETH_ALEN); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, array, NULL); - g_byte_array_unref (array); + if (!nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, NULL, ETH_ALEN)) { + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->perm_hw_addr, NULL); mac_prop = NULL; - if (mac && memcmp (priv->perm_hw_addr, mac, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (priv->perm_hw_addr, -1, mac, -1)) mac_prop = NM_SETTING_WIRED_CLONED_MAC_ADDRESS; } - if (mac_prop && mac && maclen == ETH_ALEN) { - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, (guint8 *) mac, maclen); - g_object_set (s_wired, mac_prop, array, NULL); - g_byte_array_unref (array); - } + if (mac_prop && mac && nm_utils_hwaddr_valid (mac, ETH_ALEN)) + g_object_set (s_wired, mac_prop, mac, NULL); /* We don't set the MTU as we don't know whether it was set explicitly */ /* s390 */ if (priv->subchannels) { - GPtrArray *subchan_arr = g_ptr_array_sized_new (3); - if (priv->subchan1) - g_ptr_array_add (subchan_arr, priv->subchan1); - if (priv->subchan2) - g_ptr_array_add (subchan_arr, priv->subchan2); - if (priv->subchan3) - g_ptr_array_add (subchan_arr, priv->subchan3); - g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, NULL); - g_ptr_array_free (subchan_arr, TRUE); + char **subchannels = g_new (char *, 3 + 1); + + subchannels[0] = g_strdup (priv->subchan1); + subchannels[1] = g_strdup (priv->subchan2); + subchannels[2] = g_strdup (priv->subchan3); + subchannels[3] = NULL; + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels, NULL); + g_strfreev (subchannels); } if (priv->s390_nettype) g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL); @@ -1595,7 +1560,8 @@ update_connection (NMDevice *device, NMConnection *connection) static void get_link_speed (NMDevice *device) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); struct ifreq ifr; struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET, @@ -1605,7 +1571,7 @@ get_link_speed (NMDevice *device) fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW | LOGD_ETHER, "couldn't open ethtool control socket."); + _LOGW (LOGD_HW | LOGD_ETHER, "couldn't open ethtool control socket."); return; } @@ -1633,8 +1599,7 @@ get_link_speed (NMDevice *device) priv->speed = speed; g_object_notify (G_OBJECT (device), "speed"); - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): speed is now %d Mb/s", - nm_device_get_iface (device), speed); + _LOGD (LOGD_HW | LOGD_ETHER, "speed is now %d Mb/s", speed); } static void @@ -1669,6 +1634,8 @@ finalize (GObject *object) NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); + g_free (priv->perm_hw_addr); + g_free (priv->initial_hw_addr); g_clear_object (&priv->supplicant.mgr); g_free (priv->subchan1); g_free (priv->subchan2); @@ -1689,7 +1656,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); + g_value_set_string (value, priv->perm_hw_addr); break; case PROP_SPEED: g_value_set_uint (value, priv->speed); @@ -1733,6 +1700,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->update_initial_hw_address = update_initial_hw_address; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; + parent_class->new_default_connection = new_default_connection; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->act_stage2_config = act_stage2_config; @@ -1748,23 +1716,42 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SPEED, - g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, - "Speed", - "Speed", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_ethernet_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_ETHERNET_ERROR, NULL, NM_TYPE_ETHERNET_ERROR); +#define NM_TYPE_ETHERNET_FACTORY (nm_ethernet_factory_get_type ()) +#define NM_ETHERNET_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ETHERNET_FACTORY, NMEthernetFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_ETHERNET) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_ETHERNET, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Ethernet", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NULL); + } + return NULL; } + +DEFINE_DEVICE_FACTORY_INTERNAL(ETHERNET, Ethernet, ethernet, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-ethernet.h b/src/devices/nm-device-ethernet.h index bcaf270a..ad9ce856 100644 --- a/src/devices/nm-device-ethernet.h +++ b/src/devices/nm-device-ethernet.h @@ -19,8 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_ETHERNET_H -#define NM_DEVICE_ETHERNET_H +#ifndef __NETWORKMANAGER_DEVICE_ETHERNET_H__ +#define __NETWORKMANAGER_DEVICE_ETHERNET_H__ #include @@ -35,31 +35,14 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_ETHERNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_ETHERNET)) #define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass)) -typedef enum -{ - NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED = 0, /*< nick=ConnectionNotWired >*/ - NM_ETHERNET_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMEthernetError; - #define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_ETHERNET_SPEED "speed" -typedef struct { - NMDevice parent; -} NMDeviceEthernet; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceEthernetClass; - +typedef NMDevice NMDeviceEthernet; +typedef NMDeviceClass NMDeviceEthernetClass; GType nm_device_ethernet_get_type (void); - -NMDevice *nm_device_ethernet_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_ETHERNET_H */ diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index fc4d1c24..abfb8d4a 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -18,6 +18,8 @@ * Copyright (C) 2014 Red Hat, Inc. */ +#include "config.h" + #include "nm-device-factory.h" enum { @@ -27,6 +29,21 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +static GSList *internal_types = NULL; + +void +_nm_device_factory_internal_register_type (GType factory_type) +{ + g_return_if_fail (g_slist_find (internal_types, GUINT_TO_POINTER (factory_type)) == NULL); + internal_types = g_slist_prepend (internal_types, GUINT_TO_POINTER (factory_type)); +} + +const GSList * +nm_device_factory_get_internal_factory_types (void) +{ + return internal_types; +} + gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component) { @@ -91,6 +108,23 @@ nm_device_factory_get_type (void) return device_factory_type; } +NMDeviceType +nm_device_factory_get_device_type (NMDeviceFactory *factory) +{ + g_return_val_if_fail (factory != NULL, NM_DEVICE_TYPE_UNKNOWN); + + return NM_DEVICE_FACTORY_GET_INTERFACE (factory)->get_device_type (factory); +} + +void +nm_device_factory_start (NMDeviceFactory *factory) +{ + g_return_if_fail (factory != NULL); + + if (NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start) + NM_DEVICE_FACTORY_GET_INTERFACE (factory)->start (factory); +} + NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, NMPlatformLink *plink, @@ -104,3 +138,21 @@ nm_device_factory_new_link (NMDeviceFactory *factory, return NULL; } +NMDevice * +nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + NMDeviceFactory *interface; + + g_return_val_if_fail (factory, NULL); + g_return_val_if_fail (connection, NULL); + g_return_val_if_fail (!error || !*error, NULL); + + interface = NM_DEVICE_FACTORY_GET_INTERFACE (factory); + if (interface->create_virtual_device_for_connection) + return interface->create_virtual_device_for_connection (factory, connection, parent, error); + return NULL; +} + diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index f0e3dc19..ce672b8b 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -18,14 +18,13 @@ * Copyright (C) 2007 - 2014 Red Hat, Inc. */ -#ifndef NM_DEVICE_FACTORY_H -#define NM_DEVICE_FACTORY_H +#ifndef __NETWORKMANAGER_DEVICE_FACTORY_H__ +#define __NETWORKMANAGER_DEVICE_FACTORY_H__ #include #include -#include "NetworkManager.h" -#include "nm-platform.h" +#include "nm-dbus-interface.h" #include "nm-device.h" /* WARNING: this file is private API between NetworkManager and its internal @@ -43,7 +42,7 @@ typedef struct _NMDeviceFactory NMDeviceFactory; * Creates a #GObject that implements the #NMDeviceFactory interface. This * function must not emit any signals or perform any actions that would cause * devices or components to be created immediately. Instead these should be - * deferred to an idle handler. + * deferred to the "start" interface method. * * Returns: the #GObject implementing #NMDeviceFactory or %NULL */ @@ -52,16 +51,6 @@ NMDeviceFactory *nm_device_factory_create (GError **error); /* Should match nm_device_factory_create() */ typedef NMDeviceFactory * (*NMDeviceFactoryCreateFunc) (GError **error); -/** - * nm_device_factory_get_device_type: - * - * Returns: the #NMDeviceType that this plugin creates - */ -NMDeviceType nm_device_factory_get_device_type (void); - -/* Should match nm_device_factory_get_device_type() */ -typedef NMDeviceType (*NMDeviceFactoryDeviceTypeFunc) (void); - /********************************************************************/ #define NM_TYPE_DEVICE_FACTORY (nm_device_factory_get_type ()) @@ -76,6 +65,25 @@ typedef NMDeviceType (*NMDeviceFactoryDeviceTypeFunc) (void); struct _NMDeviceFactory { GTypeInterface g_iface; + /** + * get_device_type: + * @factory: the #NMDeviceFactory + * + * This function MUST be implemented. + * + * Returns: the #NMDeviceType that this plugin creates + */ + NMDeviceType (*get_device_type) (NMDeviceFactory *factory); + + /** + * start: + * @factory: the #NMDeviceFactory + * + * Start the factory and discover any existing devices that the factory + * can manage. + */ + void (*start) (NMDeviceFactory *factory); + /** * new_link: * @factory: the #NMDeviceFactory @@ -95,6 +103,25 @@ struct _NMDeviceFactory { NMPlatformLink *plink, GError **error); + /** + * create_virtual_device_for_connection: + * @factory: the #NMDeviceFactory + * @connection: the #NMConnection + * @error: a @GError in case of failure + * + * Virtual device types (such as team, bond, bridge) may need to be created. + * This function tries to create a device based on the given @connection. + * + * Returns: the newly created #NMDevice. If the factory does not support the + * connection type, it should return %NULL and leave @error unset. On error + * it should set @error and return %NULL. + */ + NMDevice * (*create_virtual_device_for_connection) (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error); + + /* Signals */ /** @@ -124,13 +151,77 @@ struct _NMDeviceFactory { GType nm_device_factory_get_type (void); +NMDeviceType nm_device_factory_get_device_type (NMDeviceFactory *factory); + +void nm_device_factory_start (NMDeviceFactory *factory); + NMDevice * nm_device_factory_new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error); +NMDevice * nm_device_factory_create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error); + /* For use by implementations */ gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component); -#endif /* NM_DEVICE_FACTORY_H */ - +/************************************************************************** + * INTERNAL DEVICE FACTORY FUNCTIONS - devices provided by plugins should + * not use these functions. + **************************************************************************/ + +#define DEFINE_DEVICE_FACTORY_INTERNAL(upper, mixed, lower, dfi_code) \ + DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, upper, dfi_code) + +#define DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(upper, mixed, lower, devtype, dfi_code) \ + typedef GObject NM##mixed##Factory; \ + typedef GObjectClass NM##mixed##FactoryClass; \ + \ + static GType nm_##lower##_factory_get_type (void); \ + static void device_factory_interface_init (NMDeviceFactory *factory_iface); \ + \ + G_DEFINE_TYPE_EXTENDED (NM##mixed##Factory, nm_##lower##_factory, G_TYPE_OBJECT, 0, \ + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init) \ + _nm_device_factory_internal_register_type (g_define_type_id);) \ + \ + /* Use a module constructor to register the factory's GType at load \ + * time, which then calls _nm_device_factory_internal_register_type() \ + * to register the factory's GType with the Manager. \ + */ \ + static void __attribute__((constructor)) \ + register_device_factory_internal_##lower (void) \ + { \ + g_type_init (); \ + g_type_ensure (NM_TYPE_##upper##_FACTORY); \ + } \ + \ + static NMDeviceType \ + get_device_type (NMDeviceFactory *factory) \ + { \ + return NM_DEVICE_TYPE_##devtype; \ + } \ + \ + static void \ + device_factory_interface_init (NMDeviceFactory *factory_iface) \ + { \ + factory_iface->get_device_type = get_device_type; \ + dfi_code \ + } \ + \ + static void \ + nm_##lower##_factory_init (NM##mixed##Factory *self) \ + { \ + } \ + \ + static void \ + nm_##lower##_factory_class_init (NM##mixed##FactoryClass *lower##_class) \ + { \ + } + +void _nm_device_factory_internal_register_type (GType factory_type); +const GSList *nm_device_factory_get_internal_factory_types (void); + +#endif /* __NETWORKMANAGER_DEVICE_FACTORY_H__ */ diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index 5261c133..f103ef83 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -24,9 +24,9 @@ #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-platform.h" -#include "nm-utils.h" #include "nm-glib-compat.h" #include "nm-dbus-manager.h" +#include "nm-core-internal.h" #include "nm-device-generic-glue.h" @@ -45,19 +45,6 @@ enum { LAST_PROP }; -#define NM_DEVICE_GENERIC_ERROR (nm_device_generic_error_quark ()) - -static GQuark -nm_device_generic_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-device-generic-error"); - return quark; -} - -/**************************************************************/ - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -203,15 +190,12 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_TYPE_DESCRIPTION, - g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, - "Type Description", - "Type description", + g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_generic_object_info); - - dbus_g_error_domain_register (NM_DEVICE_GENERIC_ERROR, NULL, NM_TYPE_DEVICE_GENERIC_ERROR); } diff --git a/src/devices/nm-device-generic.h b/src/devices/nm-device-generic.h index e7b7090b..c889b1dd 100644 --- a/src/devices/nm-device-generic.h +++ b/src/devices/nm-device-generic.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_GENERIC_H -#define NM_DEVICE_GENERIC_H +#ifndef __NETWORKMANAGER_DEVICE_GENERIC_H__ +#define __NETWORKMANAGER_DEVICE_GENERIC_H__ #include @@ -34,13 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GENERIC)) #define NM_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GENERIC, NMDeviceGenericClass)) -typedef enum -{ - NM_DEVICE_GENERIC_ERROR_CONNECTION_NOT_GENERIC = 0, /*< nick=ConnectionNotGeneric >*/ - NM_DEVICE_GENERIC_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_DEVICE_GENERIC_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMDeviceGenericError; - #define NM_DEVICE_GENERIC_TYPE_DESCRIPTION "type-description" typedef struct { diff --git a/src/devices/nm-device-gre.c b/src/devices/nm-device-gre.c index 0412e993..9c25b398 100644 --- a/src/devices/nm-device-gre.c +++ b/src/devices/nm-device-gre.c @@ -21,6 +21,7 @@ #include "config.h" #include +#include #include "nm-device-gre.h" #include "nm-device-private.h" @@ -28,9 +29,14 @@ #include "nm-logging.h" #include "nm-manager.h" #include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-gre-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceGre); + G_DEFINE_TYPE (NMDeviceGre, nm_device_gre, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_GRE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GRE, NMDeviceGrePrivate)) @@ -60,13 +66,13 @@ enum { static void update_properties (NMDevice *device) { - NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (device); + NMDeviceGre *self = NM_DEVICE_GRE (device); + NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (self); GObject *object = G_OBJECT (device); NMPlatformGreProperties props; if (!nm_platform_gre_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read gre properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read gre properties"); return; } @@ -107,18 +113,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_gre_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GRE, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Gre", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_gre_init (NMDeviceGre *self) { @@ -194,85 +188,98 @@ nm_device_gre_class_init (NMDeviceGreClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_GRE_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_GRE_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INPUT_FLAGS, - g_param_spec_uint (NM_DEVICE_GRE_INPUT_FLAGS, - "Input flags", - "Input flags", + g_param_spec_uint (NM_DEVICE_GRE_INPUT_FLAGS, "", "", 0, G_MAXUINT16, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_OUTPUT_FLAGS, - g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_FLAGS, - "Output flags", - "Output flags", + g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_FLAGS, "", "", 0, G_MAXUINT16, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INPUT_KEY, - g_param_spec_uint (NM_DEVICE_GRE_INPUT_KEY, - "Input key", - "Input key", + g_param_spec_uint (NM_DEVICE_GRE_INPUT_KEY, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_OUTPUT_KEY, - g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_KEY, - "Output key", - "Output key", + g_param_spec_uint (NM_DEVICE_GRE_OUTPUT_KEY, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LOCAL, - g_param_spec_string (NM_DEVICE_GRE_LOCAL, - "Local", - "Local", + g_param_spec_string (NM_DEVICE_GRE_LOCAL, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_REMOTE, - g_param_spec_string (NM_DEVICE_GRE_REMOTE, - "Remote", - "Remote", + g_param_spec_string (NM_DEVICE_GRE_REMOTE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TTL, - g_param_spec_uchar (NM_DEVICE_GRE_TTL, - "TTL", - "TTL", + g_param_spec_uchar (NM_DEVICE_GRE_TTL, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TOS, - g_param_spec_uchar (NM_DEVICE_GRE_TOS, - "ToS", - "ToS", + g_param_spec_uchar (NM_DEVICE_GRE_TOS, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH_MTU_DISCOVERY, - g_param_spec_boolean (NM_DEVICE_GRE_PATH_MTU_DISCOVERY, - "Path MTU Discovery", - "Path MTU Discovery", + g_param_spec_boolean (NM_DEVICE_GRE_PATH_MTU_DISCOVERY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_gre_object_info); } + +/*************************************************************/ + +#define NM_TYPE_GRE_FACTORY (nm_gre_factory_get_type ()) +#define NM_GRE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GRE_FACTORY, NMGreFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_GRE || plink->type == NM_LINK_TYPE_GRETAP) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GRE, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Gre", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(GRE, Gre, gre, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-gre.h b/src/devices/nm-device-gre.h index 610b3805..7acff5f7 100644 --- a/src/devices/nm-device-gre.h +++ b/src/devices/nm-device-gre.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_GRE_H -#define NM_DEVICE_GRE_H +#ifndef __NETWORKMANAGER_DEVICE_GRE_H__ +#define __NETWORKMANAGER_DEVICE_GRE_H__ #include @@ -45,19 +45,11 @@ G_BEGIN_DECLS #define NM_DEVICE_GRE_TOS "tos" #define NM_DEVICE_GRE_PATH_MTU_DISCOVERY "path-mtu-discovery" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceGre; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceGreClass; +typedef NMDeviceGeneric NMDeviceGre; +typedef NMDeviceGenericClass NMDeviceGreClass; GType nm_device_gre_get_type (void); -NMDevice *nm_device_gre_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_GRE_H */ diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 8ec79157..e1af8995 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -24,15 +24,18 @@ #include #include -#include #include "nm-device-infiniband.h" #include "nm-logging.h" -#include "nm-utils.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" +#include "nm-platform.h" +#include "nm-device-factory.h" +#include "nm-core-internal.h" #include "nm-device-infiniband-glue.h" @@ -41,8 +44,6 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) #define NM_DEVICE_INFINIBAND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandPrivate)) -#define NM_INFINIBAND_ERROR (nm_infiniband_error_quark ()) - typedef struct { int dummy; } NMDeviceInfinibandPrivate; @@ -53,88 +54,11 @@ enum { LAST_PROP }; -static GQuark -nm_infiniband_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-infiniband-error"); - return quark; -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMDevice *self; - - object = G_OBJECT_CLASS (nm_device_infiniband_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - self = NM_DEVICE (object); - - nm_log_dbg (LOGD_HW | LOGD_INFINIBAND, "(%s): kernel ifindex %d", - nm_device_get_iface (self), - nm_device_get_ifindex (self)); - return object; -} - static void nm_device_infiniband_init (NMDeviceInfiniband * self) { } -NMDevice * -nm_device_infiniband_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "InfiniBand", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, - NULL); -} - -NMDevice * -nm_device_infiniband_new_partition (NMConnection *connection, - NMDevice *parent) -{ - NMSettingInfiniband *s_infiniband; - int p_key, parent_ifindex; - const char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (parent), NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - parent_ifindex = nm_device_get_ifindex (parent); - s_infiniband = nm_connection_get_setting_infiniband (connection); - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - - if ( !nm_platform_infiniband_partition_add (parent_ifindex, p_key) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_INFINIBAND, "(%s): failed to add InfiniBand P_Key interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, nm_device_get_driver (parent), - NM_DEVICE_TYPE_DESC, "InfiniBand", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, - NULL); -} - static guint32 get_generic_capabilities (NMDevice *dev) { @@ -207,14 +131,13 @@ ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) /* MTU override */ mtu = nm_setting_infiniband_get_mtu (s_infiniband); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband; - const GByteArray *mac; if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -227,11 +150,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; if (s_infiniband) { + const char *mac; + mac = nm_setting_infiniband_get_mac_address (s_infiniband); - /* We only compare the last 8 bytes */ - if (mac && memcmp (mac->data + INFINIBAND_ALEN - 8, - nm_device_get_hw_address (device, NULL) + INFINIBAND_ALEN - 8, - 8)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1)) return FALSE; } @@ -246,13 +168,14 @@ complete_connection (NMDevice *device, GError **error) { NMSettingInfiniband *s_infiniband; - const GByteArray *setting_mac; - const guint8 *hw_address; + const char *setting_mac; + const char *hw_address; nm_utils_complete_generic (connection, NM_SETTING_INFINIBAND_SETTING_NAME, existing_connections, - _("InfiniBand connection %d"), + NULL, + _("InfiniBand connection"), NULL, TRUE); @@ -263,24 +186,20 @@ complete_connection (NMDevice *device, } setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband); - hw_address = nm_device_get_hw_address (device, NULL); + hw_address = nm_device_get_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's MAC */ - if (memcmp (setting_mac->data, hw_address, INFINIBAND_ALEN)) { + if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { g_set_error_literal (error, - NM_SETTING_INFINIBAND_ERROR, - NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY, - NM_SETTING_INFINIBAND_MAC_ADDRESS); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - /* Lock the connection to this device by default */ - mac = g_byte_array_sized_new (INFINIBAND_ALEN); - g_byte_array_append (mac, hw_address, INFINIBAND_ALEN); - g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_MAC_ADDRESS, hw_address, NULL); } if (!nm_setting_infiniband_get_transport_mode (s_infiniband)) @@ -293,10 +212,7 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); - guint maclen; - gconstpointer mac = nm_device_get_hw_address (device, &maclen); - static const guint8 null_mac[INFINIBAND_ALEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - GByteArray *array; + const char *mac = nm_device_get_hw_address (device); char *mode_path, *contents = NULL; const char *transport_mode = "datagram"; @@ -305,12 +221,8 @@ update_connection (NMDevice *device, NMConnection *connection) nm_connection_add_setting (connection, (NMSetting *) s_infiniband); } - if (mac && (maclen == INFINIBAND_ALEN) && (memcmp (mac, null_mac, maclen) != 0)) { - array = g_byte_array_sized_new (maclen); - g_byte_array_append (array, (guint8 *) mac, maclen); - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, array, NULL); - g_byte_array_unref (array); - } + if (mac && !nm_utils_hwaddr_matches (mac, -1, NULL, INFINIBAND_ALEN)) + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); mode_path = g_strdup_printf ("/sys/class/net/%s/mode", ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (device))); @@ -326,38 +238,6 @@ update_connection (NMDevice *device, NMConnection *connection) g_object_set (G_OBJECT (s_infiniband), NM_SETTING_INFINIBAND_TRANSPORT_MODE, transport_mode, NULL); } -static gboolean -spec_match_list (NMDevice *device, const GSList *specs) -{ - char *hwaddr_str, *spec_str; - const GSList *iter; - - if (NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->spec_match_list (device, specs)) - return TRUE; - - hwaddr_str = nm_utils_hwaddr_ntoa (nm_device_get_hw_address (device, NULL), - ARPHRD_INFINIBAND); - - /* InfiniBand hardware address matches only need to match the last - * 8 bytes. In string format, that means we skip the first 36 - * characters of hwaddr_str, and the first 40 of the spec (to skip - * "mac:" too). - */ - for (iter = specs; iter; iter = g_slist_next (iter)) { - spec_str = iter->data; - - if ( !g_ascii_strncasecmp (spec_str, "mac:", 4) - && strlen (spec_str) > 40 - && !g_ascii_strcasecmp (spec_str + 40, hwaddr_str + 36)) { - g_free (hwaddr_str); - return TRUE; - } - } - - g_free (hwaddr_str); - return FALSE; -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -389,7 +269,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) g_type_class_add_private (object_class, sizeof (NMDeviceInfinibandPrivate)); /* virtual methods */ - object_class->constructor = constructor; object_class->get_property = get_property; object_class->set_property = set_property; @@ -397,7 +276,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; parent_class->update_connection = update_connection; - parent_class->spec_match_list = spec_match_list; parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->ip4_config_pre_commit = ip4_config_pre_commit; @@ -407,6 +285,67 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_infiniband_object_info); +} - dbus_g_error_domain_register (NM_INFINIBAND_ERROR, NULL, NM_TYPE_INFINIBAND_ERROR); +/*************************************************************/ + +#define NM_TYPE_INFINIBAND_FACTORY (nm_infiniband_factory_get_type ()) +#define NM_INFINIBAND_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INFINIBAND_FACTORY, NMInfinibandFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_INFINIBAND) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "InfiniBand", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, + NULL); + } + return NULL; } + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + NMSettingInfiniband *s_infiniband; + int p_key, parent_ifindex; + const char *iface; + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (parent), NULL); + + s_infiniband = nm_connection_get_setting_infiniband (connection); + + iface = nm_setting_infiniband_get_virtual_interface_name (s_infiniband); + g_return_val_if_fail (iface != NULL, NULL); + + parent_ifindex = nm_device_get_ifindex (parent); + p_key = nm_setting_infiniband_get_p_key (s_infiniband); + + if ( !nm_platform_infiniband_partition_add (parent_ifindex, p_key) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_INFINIBAND, "(%s): failed to add InfiniBand P_Key interface for '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_INFINIBAND, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, nm_device_get_driver (parent), + NM_DEVICE_TYPE_DESC, "InfiniBand", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_INFINIBAND, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL(INFINIBAND, Infiniband, infiniband, \ + factory_iface->new_link = new_link; \ + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-infiniband.h b/src/devices/nm-device-infiniband.h index 45dc1ab6..b81b762a 100644 --- a/src/devices/nm-device-infiniband.h +++ b/src/devices/nm-device-infiniband.h @@ -18,8 +18,8 @@ * Copyright 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_INFINIBAND_H -#define NM_DEVICE_INFINIBAND_H +#ifndef __NETWORKMANAGER_DEVICE_INFINIBAND_H__ +#define __NETWORKMANAGER_DEVICE_INFINIBAND_H__ #include @@ -34,28 +34,11 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_INFINIBAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_INFINIBAND)) #define NM_DEVICE_INFINIBAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_INFINIBAND, NMDeviceInfinibandClass)) -typedef enum { - NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND = 0, /*< nick=ConnectionNotInfiniband >*/ - NM_INFINIBAND_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMInfinibandError; - -typedef struct { - NMDevice parent; -} NMDeviceInfiniband; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceInfinibandClass; - +typedef NMDevice NMDeviceInfiniband; +typedef NMDeviceClass NMDeviceInfinibandClass; GType nm_device_infiniband_get_type (void); -NMDevice *nm_device_infiniband_new (NMPlatformLink *platform_device); -NMDevice *nm_device_infiniband_new_partition (NMConnection *connection, - NMDevice *parent); - G_END_DECLS #endif /* NM_DEVICE_INFINIBAND_H */ diff --git a/src/devices/nm-device-logging.h b/src/devices/nm-device-logging.h new file mode 100644 index 00000000..acca32e5 --- /dev/null +++ b/src/devices/nm-device-logging.h @@ -0,0 +1,46 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DEVICE_LOGGING_H__ +#define __NETWORKMANAGER_DEVICE_LOGGING_H__ + +#include "nm-logging.h" +#include "nm-device.h" + +#define _LOG_DECLARE_SELF(t) \ +inline static NMDevice * \ +_nm_device_log_self_to_device (t *self) \ +{ \ + return (NMDevice *) self; \ +} + +#define _LOG(level, domain, ...) \ + nm_log_obj ((level), (domain), (self), \ + "(%s): " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + (self) ? str_if_set (nm_device_get_iface (_nm_device_log_self_to_device (self)), "(null)") : "(none)" \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +#define _LOGT(domain, ...) _LOG (LOGL_TRACE, domain, __VA_ARGS__) +#define _LOGD(domain, ...) _LOG (LOGL_DEBUG, domain, __VA_ARGS__) +#define _LOGI(domain, ...) _LOG (LOGL_INFO, domain, __VA_ARGS__) +#define _LOGW(domain, ...) _LOG (LOGL_WARN, domain, __VA_ARGS__) +#define _LOGE(domain, ...) _LOG (LOGL_ERR, domain, __VA_ARGS__) + +#endif /* __NETWORKMANAGER_DEVICE_LOGGING_H__ */ diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index 22848fe7..bcd38617 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -28,9 +28,13 @@ #include "nm-logging.h" #include "nm-manager.h" #include "nm-platform.h" +#include "nm-device-factory.h" #include "nm-device-macvlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceMacvlan); + G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate)) @@ -55,13 +59,13 @@ enum { static void update_properties (NMDevice *device) { + NMDeviceMacvlan *self = NM_DEVICE_MACVLAN (device); NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformMacvlanProperties props; if (!nm_platform_macvlan_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read macvlan properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read macvlan properties"); return; } @@ -88,18 +92,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_macvlan_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Macvlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_macvlan_init (NMDeviceMacvlan *self) { @@ -153,29 +145,49 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_MACVLAN_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_MACVLAN_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_string (NM_DEVICE_MACVLAN_MODE, - "Mode", - "Mode: 'private', 'vepa', 'bridge', or 'passthru'", + g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NO_PROMISC, - g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, - "No-promisc", - "No promiscuous mode", + g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_macvlan_object_info); } + +/*************************************************************/ + +#define NM_TYPE_MACVLAN_FACTORY (nm_macvlan_factory_get_type ()) +#define NM_MACVLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MACVLAN_FACTORY, NMMacvlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_MACVLAN || plink->type == NM_LINK_TYPE_MACVTAP) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MACVLAN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Macvlan", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(MACVLAN, Macvlan, macvlan, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-macvlan.h b/src/devices/nm-device-macvlan.h index 348ed2f9..24f15437 100644 --- a/src/devices/nm-device-macvlan.h +++ b/src/devices/nm-device-macvlan.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_MACVLAN_H -#define NM_DEVICE_MACVLAN_H +#ifndef __NETWORKMANAGER_DEVICE_MACVLAN_H__ +#define __NETWORKMANAGER_DEVICE_MACVLAN_H__ #include @@ -38,19 +38,11 @@ G_BEGIN_DECLS #define NM_DEVICE_MACVLAN_MODE "mode" #define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceMacvlan; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceMacvlanClass; +typedef NMDeviceGeneric NMDeviceMacvlan; +typedef NMDeviceGenericClass NMDeviceMacvlanClass; GType nm_device_macvlan_get_type (void); -NMDevice *nm_device_macvlan_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_MACVLAN_H */ diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 24bb0b33..65a9a71a 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_PRIVATE_H -#define NM_DEVICE_PRIVATE_H +#ifndef __NETWORKMANAGER_DEVICE_PRIVATE_H__ +#define __NETWORKMANAGER_DEVICE_PRIVATE_H__ #include "nm-device.h" @@ -37,8 +37,9 @@ enum NMActStageReturn { }; #define NM_DEVICE_CAP_NONSTANDARD_CARRIER 0x80000000 +#define NM_DEVICE_CAP_IS_NON_KERNEL 0x40000000 -#define NM_DEVICE_CAP_INTERNAL_MASK 0x80000000 +#define NM_DEVICE_CAP_INTERNAL_MASK 0xc0000000 void nm_device_set_ip_iface (NMDevice *self, const char *iface); @@ -52,12 +53,9 @@ gboolean nm_device_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmwar void nm_device_take_down (NMDevice *self, gboolean block); -gboolean nm_device_update_hw_address (NMDevice *self); -gboolean nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, +gboolean nm_device_set_hw_addr (NMDevice *device, const char *addr, const char *detail, guint64 hw_log_domain); -gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6); - void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); @@ -76,7 +74,7 @@ gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device); gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device); void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); -void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); +void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr); gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); gboolean nm_device_dhcp6_renew (NMDevice *device, gboolean release); @@ -91,12 +89,17 @@ gboolean nm_device_get_enslaved (NMDevice *device); NMDevice *nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex); -void nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, +void nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, guint64 log_domain); -void nm_device_set_carrier (NMDevice *device, gboolean carrier); +void nm_device_set_carrier (NMDevice *self, gboolean carrier); void nm_device_emit_recheck_auto_activate (NMDevice *device); void nm_device_queue_recheck_assume (NMDevice *device); +void nm_device_set_wwan_ip4_config (NMDevice *device, NMIP4Config *config); +void nm_device_set_wwan_ip6_config (NMDevice *device, NMIP6Config *config); + +gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-team.c b/src/devices/nm-device-team.c deleted file mode 100644 index f3b25e3b..00000000 --- a/src/devices/nm-device-team.c +++ /dev/null @@ -1,894 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * Copyright (C) 2013 Jiri Pirko - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#if WITH_TEAMDCTL -#include -#endif -#include - -#include "nm-device-team.h" -#include "nm-logging.h" -#include "nm-utils.h" -#include "NetworkManagerUtils.h" -#include "nm-device-private.h" -#include "nm-platform.h" -#include "nm-dbus-glib-types.h" -#include "nm-dbus-manager.h" -#include "nm-enum-types.h" -#include "nm-posix-signals.h" - -#include "nm-device-team-glue.h" - - -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)) - -#define NM_TEAM_ERROR (nm_team_error_quark ()) - -static gboolean teamd_start (NMDevice *dev, NMSettingTeam *s_team); - -typedef struct { -#if WITH_TEAMDCTL - struct teamdctl *tdc; -#endif - GPid teamd_pid; - guint teamd_process_watch; - guint teamd_timeout; - guint teamd_dbus_watch; -} NMDeviceTeamPrivate; - -enum { - PROP_0, - PROP_SLAVES, - - LAST_PROP -}; - -/******************************************************************/ - -static GQuark -nm_team_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-team-error"); - return quark; -} - -/******************************************************************/ - -static guint32 -get_generic_capabilities (NMDevice *dev) -{ - return NM_DEVICE_CAP_CARRIER_DETECT; -} - -static gboolean -is_available (NMDevice *dev) -{ - if (NM_DEVICE_GET_CLASS (dev)->is_up) - return NM_DEVICE_GET_CLASS (dev)->is_up (dev); - return FALSE; -} - -static gboolean -check_connection_available (NMDevice *device, - NMConnection *connection, - const char *specific_object) -{ - /* Connections are always available because the carrier state is determined - * by the team port carrier states, not the team's state. - */ - return TRUE; -} - -static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection) -{ - const char *iface; - NMSettingTeam *s_team; - - if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection)) - return FALSE; - - s_team = nm_connection_get_setting_team (connection); - if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) - return FALSE; - - /* Team connections must specify the virtual interface name */ - iface = nm_connection_get_virtual_iface_name (connection); - if (!iface || strcmp (nm_device_get_iface (device), iface)) - return FALSE; - - /* FIXME: match team properties like mode, etc? */ - - return TRUE; -} - -static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - const GSList *existing_connections, - GError **error) -{ - NMSettingTeam *s_team, *tmp; - guint32 i = 0; - char *name; - const GSList *iter; - gboolean found; - - nm_utils_complete_generic (connection, - NM_SETTING_TEAM_SETTING_NAME, - existing_connections, - _("Team connection %d"), - NULL, - TRUE); - - s_team = nm_connection_get_setting_team (connection); - if (!s_team) { - s_team = (NMSettingTeam *) nm_setting_team_new (); - nm_connection_add_setting (connection, NM_SETTING (s_team)); - } - - /* Grab the first name that doesn't exist in either our connections - * or a device on the system. - */ - while (i < 500 && !nm_setting_team_get_interface_name (s_team)) { - name = g_strdup_printf ("team%u", i); - /* check interface names */ - if (!nm_platform_link_exists (name)) { - /* check existing team connections */ - for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; - - tmp = nm_connection_get_setting_team (candidate); - if (tmp && nm_connection_is_type (candidate, NM_SETTING_TEAM_SETTING_NAME)) { - if (g_strcmp0 (nm_setting_team_get_interface_name (tmp), name) == 0) { - found = TRUE; - break; - } - } - } - - if (!found) - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_INTERFACE_NAME, name, NULL); - } - - g_free (name); - i++; - } - - return TRUE; -} - -#if WITH_TEAMDCTL -static gboolean -ensure_teamd_connection (NMDevice *self) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - int err; - - if (priv->tdc) - return TRUE; - - priv->tdc = teamdctl_alloc (); - g_assert (priv->tdc); - err = teamdctl_connect (priv->tdc, nm_device_get_iface (self), NULL, NULL); - if (err != 0) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd (err=%d)", - nm_device_get_iface (self), err); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } - - return !!priv->tdc; -} -#endif - -static void -update_connection (NMDevice *device, NMConnection *connection) -{ - NMSettingTeam *s_team = nm_connection_get_setting_team (connection); - const char *iface = nm_device_get_iface (device); - - if (!s_team) { - 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_INTERFACE_NAME, iface, NULL); - } - g_object_set (G_OBJECT (s_team), NM_SETTING_TEAM_CONFIG, NULL, NULL); - -#if WITH_TEAMDCTL - teamd_start (device, s_team); - if (NM_DEVICE_TEAM_GET_PRIVATE (device)->teamd_pid > 0 && ensure_teamd_connection (device)) { - const char *config = NULL; - int err; - - 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 - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd config (err=%d)", iface, err); - } -#endif -} - -/******************************************************************/ - -gboolean -nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection) -{ - NMSettingTeamPort *s_port; - const char *iface = nm_device_get_iface (slave); - char *port_config = NULL; - gboolean with_teamdctl = FALSE; - int err = 0; -#if WITH_TEAMDCTL - const char *master_iface; - int master_ifindex; - struct teamdctl *tdc; - const char *team_port_config = NULL; -#endif - - g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - -#if WITH_TEAMDCTL - master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave)); - g_assert (master_ifindex > 0); - master_iface = nm_platform_link_get_name (master_ifindex); - g_assert (master_iface); - - tdc = teamdctl_alloc (); - g_assert (tdc); - err = teamdctl_connect (tdc, master_iface, NULL, NULL); - if (err) { - nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)", - iface, master_iface, err); - teamdctl_free (tdc); - return FALSE; - } - err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config); - port_config = g_strdup (team_port_config); - teamdctl_free (tdc); - with_teamdctl = TRUE; -#endif - - s_port = nm_connection_get_setting_team_port (connection); - if (!s_port) { - s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); - nm_connection_add_setting (connection, NM_SETTING (s_port)); - } - - g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); - g_free (port_config); - - if (!with_teamdctl || err != 0) { - if (!with_teamdctl) - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration " - " (compiled without libteamdctl support)", iface); - else - nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)", - iface, err); - return FALSE; - } - - return TRUE; -} - -/******************************************************************/ - -static gboolean -ensure_killed (gpointer data) -{ - int pid = GPOINTER_TO_INT (data); - - if (kill (pid, 0) == 0) - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_TEAM, "waiting for teamd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_TEAM, "teamd pid %d cleaned up", pid); - - return FALSE; -} - -static void -service_kill (int pid) -{ - if (kill (pid, SIGTERM) == 0) - g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (pid)); - else { - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_TEAM, "waiting for teamd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_TEAM, "teamd pid %d cleaned up", pid); - } -} - -static void -teamd_timeout_remove (NMDevice *dev) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - if (priv->teamd_timeout) { - g_source_remove (priv->teamd_timeout); - priv->teamd_timeout = 0; - } -} - -static void -teamd_cleanup (NMDevice *dev, gboolean device_state_failed) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - if (priv->teamd_dbus_watch) { - g_bus_unwatch_name (priv->teamd_dbus_watch); - priv->teamd_dbus_watch = 0; - } - - if (priv->teamd_process_watch) { - g_source_remove (priv->teamd_process_watch); - priv->teamd_process_watch = 0; - } - - if (priv->teamd_pid > 0) { - service_kill (priv->teamd_pid); - priv->teamd_pid = 0; - } - -#if WITH_TEAMDCTL - if (priv->tdc) { - teamdctl_disconnect (priv->tdc); - teamdctl_free (priv->tdc); - priv->tdc = NULL; - } -#endif - - teamd_timeout_remove (dev); - - if (device_state_failed) { - if (nm_device_is_activating (dev) || - (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - } -} - -static gboolean -teamd_timeout_cb (gpointer user_data) -{ - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - g_return_val_if_fail (priv->teamd_timeout, FALSE); - - nm_log_info (LOGD_TEAM, "(%s): teamd timed out.", nm_device_get_iface (dev)); - teamd_cleanup (dev, TRUE); - - return FALSE; -} - -static void -teamd_dbus_appeared (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) -{ - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - g_return_if_fail (priv->teamd_dbus_watch); - - nm_log_info (LOGD_TEAM, "(%s): teamd appeared on D-Bus", nm_device_get_iface (dev)); - teamd_timeout_remove (dev); -#if WITH_TEAMDCTL - if (!ensure_teamd_connection (dev)) { - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); - return; - } -#endif - nm_device_activate_schedule_stage2_device_config (dev); -} - -static void -teamd_dbus_vanished (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - g_return_if_fail (priv->teamd_dbus_watch); - - if (priv->teamd_timeout) { - /* 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, until the - * startup timeout is over. - * - * Note that g_bus_watch_name is guaranteed to alternate vanished/appeared signals, - * so we won't hit this condition again (because the next signal is either 'appeared' - * or 'timeout'). */ - nm_log_dbg (LOGD_TEAM, "(%s): teamd vanished from D-Bus (ignored)", nm_device_get_iface (dev)); - return; - } - - nm_log_info (LOGD_TEAM, "(%s): teamd vanished from D-Bus", nm_device_get_iface (dev)); - teamd_cleanup (dev, TRUE); -} - -static void -teamd_process_watch_cb (GPid pid, gint status, gpointer user_data) -{ - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - g_return_if_fail (priv->teamd_process_watch); - - nm_log_info (LOGD_TEAM, "(%s): teamd died", nm_device_get_iface (dev)); - priv->teamd_process_watch = 0; - priv->teamd_pid = 0; - teamd_cleanup (dev, TRUE); -} - -static void -teamd_child_setup (gpointer user_data G_GNUC_UNUSED) -{ - /* We are in the child process at this point. - * Give child it's own program group for signal - * separation. - */ - pid_t pid = getpid (); - setpgid (pid, pid); - - /* - * We blocked signals in main(). We need to restore original signal - * mask for avahi-autoipd here so that it can receive signals. - */ - nm_unblock_posix_signals (NULL); -} - -static gboolean -teamd_start (NMDevice *dev, NMSettingTeam *s_team) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - const char *iface = nm_device_get_ip_iface (dev); - char *tmp_str; - const char *config; - const char **teamd_binary = NULL; - static const char *teamd_paths[] = { - "/usr/bin/teamd", - "/usr/local/bin/teamd", - NULL - }; - GPtrArray *argv; - GError *error = NULL; - gboolean ret; - int status; - - if (priv->teamd_dbus_watch || - priv->teamd_process_watch || - priv->teamd_pid > 0 || -#if WITH_TEAMDCTL - priv->tdc || -#endif - priv->teamd_timeout) - { - /* Just return if teamd_start() was already called */ - return TRUE; - } - - teamd_binary = teamd_paths; - while (*teamd_binary != NULL) { - if (g_file_test (*teamd_binary, G_FILE_TEST_EXISTS)) - break; - teamd_binary++; - } - - if (!*teamd_binary) { - nm_log_warn (LOGD_TEAM, - "Activation (%s) failed to start teamd: teamd binary not found", - iface); - return FALSE; - } - - /* Kill teamd for same named device first if it is there */ - argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) *teamd_binary); - g_ptr_array_add (argv, (gpointer) "-k"); - g_ptr_array_add (argv, (gpointer) "-t"); - g_ptr_array_add (argv, (gpointer) iface); - g_ptr_array_add (argv, NULL); - - tmp_str = g_strjoinv (" ", (gchar **) argv->pdata); - nm_log_dbg (LOGD_TEAM, "running: %s", tmp_str); - g_free (tmp_str); - - ret = g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &error); - g_ptr_array_free (argv, TRUE); - - /* Start teamd now */ - argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) *teamd_binary); - g_ptr_array_add (argv, (gpointer) "-o"); - g_ptr_array_add (argv, (gpointer) "-n"); - g_ptr_array_add (argv, (gpointer) "-U"); - g_ptr_array_add (argv, (gpointer) "-D"); - g_ptr_array_add (argv, (gpointer) "-t"); - g_ptr_array_add (argv, (gpointer) iface); - - config = nm_setting_team_get_config(s_team); - if (config) { - g_ptr_array_add (argv, (gpointer) "-c"); - g_ptr_array_add (argv, (gpointer) config); - } - - if (nm_logging_enabled (LOGL_DEBUG, LOGD_TEAM)) - g_ptr_array_add (argv, (gpointer) "-gg"); - g_ptr_array_add (argv, NULL); - - tmp_str = g_strjoinv (" ", (gchar **) argv->pdata); - nm_log_dbg (LOGD_TEAM, "running: %s", tmp_str); - g_free (tmp_str); - - /* Start a timeout for teamd to appear at D-Bus */ - priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, dev); - - /* Register D-Bus name watcher */ - tmp_str = g_strdup_printf ("org.libteam.teamd.%s", iface); - priv->teamd_dbus_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - tmp_str, - G_BUS_NAME_WATCHER_FLAGS_NONE, - teamd_dbus_appeared, - teamd_dbus_vanished, - dev, - NULL); - g_free (tmp_str); - - ret = g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, - &teamd_child_setup, NULL, &priv->teamd_pid, &error); - g_ptr_array_free (argv, TRUE); - if (!ret) { - nm_log_warn (LOGD_TEAM, - "Activation (%s) failed to start teamd: %s", - iface, error->message); - g_clear_error (&error); - teamd_cleanup (dev, FALSE); - return FALSE; - } - - /* Monitor the child process so we know when it dies */ - priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid, - teamd_process_watch_cb, - dev); - - nm_log_info (LOGD_TEAM, - "Activation (%s) started teamd...", iface); - return TRUE; -} - -static void -teamd_stop (NMDevice *dev) -{ - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (dev); - - if (priv->teamd_pid > 0) { - nm_log_info (LOGD_TEAM, "Deactivation (%s) stopping teamd...", - nm_device_get_ip_iface (dev)); - } else { - nm_log_dbg (LOGD_TEAM, "Deactivation (%s) stopping teamd (not started)...", - nm_device_get_ip_iface (dev)); - } - teamd_cleanup (dev, FALSE); -} - -static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) -{ - NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - NMConnection *connection; - NMSettingTeam *s_team; - - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (dev, reason); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { - connection = nm_device_get_connection (dev); - g_assert (connection); - s_team = nm_connection_get_setting_team (connection); - g_assert (s_team); - if (teamd_start (dev, s_team)) - ret = NM_ACT_STAGE_RETURN_POSTPONE; - else - ret = NM_ACT_STAGE_RETURN_FAILURE; - } - return ret; -} - -static void -deactivate (NMDevice *dev) -{ - teamd_stop (dev); -} - -static gboolean -enslave_slave (NMDevice *device, - NMDevice *slave, - NMConnection *connection, - gboolean configure) -{ -#if WITH_TEAMDCTL - NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); -#endif - gboolean success = TRUE, no_firmware = FALSE; - const char *iface = nm_device_get_ip_iface (device); - const char *slave_iface = nm_device_get_ip_iface (slave); - NMSettingTeamPort *s_team_port; - - nm_device_master_check_slave_physical_port (device, slave, LOGD_TEAM); - - if (configure) { - nm_device_take_down (slave, TRUE); - - s_team_port = nm_connection_get_setting_team_port (connection); - if (s_team_port) { - const char *config = nm_setting_team_port_get_config (s_team_port); - - if (config) { -#if WITH_TEAMDCTL - if (!priv->tdc) { - nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed, not connected to teamd", - iface, slave_iface); - } else { - int err; - char *sanitized_config; - - sanitized_config = g_strdelimit (g_strdup (config), "\r\n", ' '); - err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); - g_free (sanitized_config); - if (err != 0) { - nm_log_err (LOGD_TEAM, "(%s): failed to update config for port %s (err=%d)", - iface, slave_iface, err); - return FALSE; - } - } -#else - nm_log_warn (LOGD_TEAM, "(%s): enslaved team port %s config not changed due to lack of Teamd control support", - iface, slave_iface); -#endif - } - } - success = nm_platform_link_enslave (nm_device_get_ip_ifindex (device), - nm_device_get_ip_ifindex (slave)); - nm_device_bring_up (slave, TRUE, &no_firmware); - - if (!success) - return FALSE; - - nm_log_info (LOGD_TEAM, "(%s): enslaved team port %s", iface, slave_iface); - } else - nm_log_info (LOGD_TEAM, "(%s): team port %s was enslaved", iface, slave_iface); - - g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); - - return TRUE; -} - -static gboolean -release_slave (NMDevice *device, - NMDevice *slave, - gboolean configure) -{ - gboolean success = TRUE, no_firmware = FALSE; - - if (configure) { - success = nm_platform_link_release (nm_device_get_ip_ifindex (device), - nm_device_get_ip_ifindex (slave)); - - if (success) { - nm_log_info (LOGD_TEAM, "(%s): released team port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } else { - nm_log_warn (LOGD_TEAM, "(%s): failed to release team port %s", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } - } else { - nm_log_info (LOGD_TEAM, "(%s): team port %s was released", - nm_device_get_ip_iface (device), - nm_device_get_ip_iface (slave)); - } - - if (success) - g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); - - if (configure) { - /* Kernel team code "closes" the port when releasing it, (which clears - * IFF_UP), so we must bring it back up here to ensure carrier changes and - * other state is noticed by the now-released port. - */ - if (!nm_device_bring_up (slave, TRUE, &no_firmware)) { - nm_log_warn (LOGD_TEAM, "(%s): released team port could not be brought up.", - nm_device_get_iface (slave)); - } - } - - return success; -} - -/******************************************************************/ - -NMDevice * -nm_device_team_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_DRIVER, "team", - NM_DEVICE_TYPE_DESC, "Team", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -NMDevice * -nm_device_team_new_for_connection (NMConnection *connection) -{ - const char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - - iface = nm_connection_get_virtual_iface_name (connection); - g_return_val_if_fail (iface != NULL, NULL); - - if ( !nm_platform_team_add (iface) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_TEAM, "(%s): failed to create team master interface for '%s': %s", - iface, nm_connection_get_id (connection), - nm_platform_get_error_msg ()); - return NULL; - } - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, - NM_DEVICE_IFACE, iface, - NM_DEVICE_DRIVER, "team", - NM_DEVICE_TYPE_DESC, "Team", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, - NM_DEVICE_IS_MASTER, TRUE, - NULL); -} - -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_team_parent_class)->constructed (object); - - nm_log_dbg (LOGD_HW | LOGD_TEAM, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (object)), - nm_device_get_ifindex (NM_DEVICE (object))); -} - -static void -nm_device_team_init (NMDeviceTeam * self) -{ -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GPtrArray *slaves; - GSList *list, *iter; - - switch (prop_id) { - break; - case PROP_SLAVES: - slaves = g_ptr_array_new (); - list = nm_device_master_get_slaves (NM_DEVICE (object)); - for (iter = list; iter; iter = iter->next) - g_ptr_array_add (slaves, g_strdup (nm_device_get_path (NM_DEVICE (iter->data)))); - g_slist_free (list); - g_value_take_boxed (value, slaves); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -dispose (GObject *object) -{ - teamd_cleanup (NM_DEVICE (object), FALSE); - - G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); -} - -static void -nm_device_team_class_init (NMDeviceTeamClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMDeviceTeamPrivate)); - - parent_class->connection_type = NM_SETTING_TEAM_SETTING_NAME; - - /* virtual methods */ - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - - parent_class->get_generic_capabilities = get_generic_capabilities; - parent_class->is_available = is_available; - parent_class->check_connection_compatible = check_connection_compatible; - parent_class->check_connection_available = check_connection_available; - parent_class->complete_connection = complete_connection; - parent_class->update_connection = update_connection; - - parent_class->act_stage1_prepare = act_stage1_prepare; - parent_class->deactivate = deactivate; - parent_class->enslave_slave = enslave_slave; - parent_class->release_slave = release_slave; - - /* properties */ - g_object_class_install_property - (object_class, PROP_SLAVES, - g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, - "Slaves", - "Slaves", - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), - G_TYPE_FROM_CLASS (klass), - &dbus_glib_nm_device_team_object_info); - - dbus_g_error_domain_register (NM_TEAM_ERROR, NULL, NM_TYPE_TEAM_ERROR); -} diff --git a/src/devices/nm-device-team.h b/src/devices/nm-device-team.h deleted file mode 100644 index fe1275c6..00000000 --- a/src/devices/nm-device-team.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * Copyright (C) 2013 Jiri Pirko - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef NM_DEVICE_TEAM_H -#define NM_DEVICE_TEAM_H - -#include - -#include "nm-device.h" - -G_BEGIN_DECLS - -#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) -#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) -#define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) -#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TEAM)) -#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)) - -typedef enum { - NM_TEAM_ERROR_CONNECTION_NOT_TEAM = 0, /*< nick=ConnectionNotTeam >*/ - NM_TEAM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_TEAM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMTeamError; - -#define NM_DEVICE_TEAM_SLAVES "slaves" - -typedef struct { - NMDevice parent; -} NMDeviceTeam; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceTeamClass; - - -GType nm_device_team_get_type (void); - -NMDevice *nm_device_team_new (NMPlatformLink *platform_device); -NMDevice *nm_device_team_new_for_connection (NMConnection *connection); - -gboolean nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection); - -G_END_DECLS - -#endif /* NM_DEVICE_TEAM_H */ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index d52228f9..9a3fab5e 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -28,9 +28,13 @@ #include "nm-dbus-manager.h" #include "nm-logging.h" #include "nm-platform.h" +#include "nm-device-factory.h" #include "nm-device-tun-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceTun); + G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_TUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_TUN, NMDeviceTunPrivate)) @@ -55,15 +59,14 @@ enum { }; static void -reload_tun_properties (NMDeviceTun *device) +reload_tun_properties (NMDeviceTun *self) { - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (device); - GObject *object = G_OBJECT (device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); + GObject *object = G_OBJECT (self); NMPlatformTunProperties props; - if (!nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (device)), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read tun properties", - nm_device_get_iface (NM_DEVICE (device))); + if (!nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (self)), &props)) { + _LOGD (LOGD_HW, "could not read tun properties"); return; } @@ -108,27 +111,6 @@ delay_tun_get_properties_cb (gpointer user_data) /**************************************************************/ -NMDevice * -nm_device_tun_new (NMPlatformLink *platform_device) -{ - const char *mode = NULL; - - g_return_val_if_fail (platform_device != NULL, NULL); - - if (platform_device->type == NM_LINK_TYPE_TUN) - mode = "tun"; - else if (platform_device->type == NM_LINK_TYPE_TAP) - mode = "tap"; - g_return_val_if_fail (mode != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Tun", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NM_DEVICE_TUN_MODE, mode, - NULL); -} - static void nm_device_tun_init (NMDeviceTun *self) { @@ -137,18 +119,18 @@ nm_device_tun_init (NMDeviceTun *self) static void constructed (GObject *object) { + NMDeviceTun *self = NM_DEVICE_TUN (object); gboolean properties_read; - NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); - properties_read = nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (object)), &priv->props); + properties_read = nm_platform_tun_get_properties (nm_device_get_ifindex (NM_DEVICE (self)), &priv->props); G_OBJECT_CLASS (nm_device_tun_parent_class)->constructed (object); if (!properties_read) { /* Error reading the tun properties. Maybe this was due to a race. Try again a bit later. */ - nm_log_dbg (LOGD_HW, "(%s): could not read tun properties (retry)", - nm_device_get_iface (NM_DEVICE (object))); - priv->delay_tun_get_properties_id = g_timeout_add_seconds (1, delay_tun_get_properties_cb, object); + _LOGD (LOGD_HW, "could not read tun properties (retry)"); + priv->delay_tun_get_properties_id = g_timeout_add_seconds (1, delay_tun_get_properties_cb, self); } } @@ -174,10 +156,10 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_OWNER: - g_value_set_uint (value, priv->props.owner); + g_value_set_int64 (value, priv->props.owner); break; case PROP_GROUP: - g_value_set_uint (value, priv->props.group); + g_value_set_int64 (value, priv->props.group); break; case PROP_MODE: g_value_set_string (value, priv->mode); @@ -242,49 +224,37 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_OWNER, - g_param_spec_int64 (NM_DEVICE_TUN_OWNER, - "Owner", - "Owner", + g_param_spec_int64 (NM_DEVICE_TUN_OWNER, "", "", -1, G_MAXUINT32, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_GROUP, - g_param_spec_int64 (NM_DEVICE_TUN_GROUP, - "Group", - "Group", + g_param_spec_int64 (NM_DEVICE_TUN_GROUP, "", "", -1, G_MAXUINT32, -1, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_string (NM_DEVICE_TUN_MODE, - "Mode", - "Mode", + g_param_spec_string (NM_DEVICE_TUN_MODE, "", "", "tun", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NO_PI, - g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, - "No Protocol Info", - "No Protocol Info", - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_param_spec_boolean (NM_DEVICE_TUN_NO_PI, "", "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_VNET_HDR, - g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, - "Virtio networking header", - "Virtio networking header", + g_param_spec_boolean (NM_DEVICE_TUN_VNET_HDR, "", "", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MULTI_QUEUE, - g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, - "Multi-queue", - "Multi-queue", + g_param_spec_boolean (NM_DEVICE_TUN_MULTI_QUEUE, "", "", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); @@ -292,3 +262,34 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_tun_object_info); } + + +/*************************************************************/ + +#define NM_TYPE_TUN_FACTORY (nm_tun_factory_get_type ()) +#define NM_TUN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TUN_FACTORY, NMTunFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + const char *mode = NULL; + + if (plink->type == NM_LINK_TYPE_TUN) + mode = "tun"; + else if (plink->type == NM_LINK_TYPE_TAP) + mode = "tap"; + else + return NULL; + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TUN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Tun", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NM_DEVICE_TUN_MODE, mode, + NULL); +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(TUN, Tun, tun, GENERIC, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-tun.h b/src/devices/nm-device-tun.h index cfcf4d7b..393c5801 100644 --- a/src/devices/nm-device-tun.h +++ b/src/devices/nm-device-tun.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_TUN_H -#define NM_DEVICE_TUN_H +#ifndef __NETWORKMANAGER_DEVICE_TUN_H__ +#define __NETWORKMANAGER_DEVICE_TUN_H__ #include @@ -41,19 +41,11 @@ G_BEGIN_DECLS #define NM_DEVICE_TUN_VNET_HDR "vnet-hdr" #define NM_DEVICE_TUN_MULTI_QUEUE "multi-queue" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceTun; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceTunClass; +typedef NMDeviceGeneric NMDeviceTun; +typedef NMDeviceGenericClass NMDeviceTunClass; GType nm_device_tun_get_type (void); -NMDevice *nm_device_tun_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_TUN_H */ diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index df107523..db29c00d 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -33,9 +33,13 @@ #include "nm-manager.h" #include "nm-platform.h" #include "nm-dbus-manager.h" +#include "nm-device-factory.h" #include "nm-device-veth-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVeth); + G_DEFINE_TYPE (NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) #define NM_DEVICE_VETH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VETH, NMDeviceVethPrivate)) @@ -79,8 +83,7 @@ get_peer (NMDeviceVeth *self) return priv->peer; if (!nm_platform_veth_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read veth properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read veth properties"); return NULL; } @@ -96,18 +99,6 @@ get_peer (NMDeviceVeth *self) /**************************************************************/ -NMDevice * -nm_device_veth_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Veth", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, - NULL); -} - static void nm_device_veth_init (NMDeviceVeth *self) { @@ -159,13 +150,35 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PEER, - g_param_spec_boxed (NM_DEVICE_VETH_PEER, - "Peer", - "Peer device", + g_param_spec_boxed (NM_DEVICE_VETH_PEER, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_veth_object_info); } + +/*************************************************************/ + +#define NM_TYPE_VETH_FACTORY (nm_veth_factory_get_type ()) +#define NM_VETH_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VETH_FACTORY, NMVethFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_VETH) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VETH, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Veth", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(VETH, Veth, veth, ETHERNET, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-veth.h b/src/devices/nm-device-veth.h index bc8fedff..51e8db45 100644 --- a/src/devices/nm-device-veth.h +++ b/src/devices/nm-device-veth.h @@ -18,8 +18,8 @@ * Copyright 2013 Red Hat, Inc. */ -#ifndef NM_DEVICE_VETH_H -#define NM_DEVICE_VETH_H +#ifndef __NETWORKMANAGER_DEVICE_VETH_H__ +#define __NETWORKMANAGER_DEVICE_VETH_H__ #include @@ -36,19 +36,11 @@ G_BEGIN_DECLS #define NM_DEVICE_VETH_PEER "peer" -typedef struct { - NMDeviceEthernet parent; -} NMDeviceVeth; - -typedef struct { - NMDeviceEthernetClass parent; - -} NMDeviceVethClass; +typedef NMDeviceEthernet NMDeviceVeth; +typedef NMDeviceEthernetClass NMDeviceVethClass; GType nm_device_veth_get_type (void); -NMDevice *nm_device_veth_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_VETH_H */ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 348be352..c69bcded 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -24,8 +24,6 @@ #include #include -#include -#include #include "nm-device-vlan.h" #include "nm-manager.h" @@ -35,20 +33,25 @@ #include "nm-device-private.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-connection-provider.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" #include "nm-platform.h" -#include "nm-utils.h" +#include "nm-device-factory.h" +#include "nm-manager.h" +#include "nm-core-internal.h" #include "nm-device-vlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVlan); G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) #define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate)) -#define NM_VLAN_ERROR (nm_vlan_error_quark ()) - typedef struct { - guint8 initial_hw_addr[ETH_ALEN]; + char *initial_hw_addr; gboolean disposed; gboolean invalid; @@ -64,35 +67,21 @@ enum { PROP_PARENT, PROP_VLAN_ID, + PROP_INT_PARENT_DEVICE, + LAST_PROP }; /******************************************************************/ -static GQuark -nm_vlan_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-vlan-error"); - return quark; -} - -/******************************************************************/ - static void update_initial_hw_address (NMDevice *dev) { NMDeviceVlan *self = NM_DEVICE_VLAN (dev); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); - char *mac_str; - memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); - - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_VLAN, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (dev)); + _LOGD (LOGD_DEVICE | LOGD_VLAN, "read initial MAC address %s", priv->initial_hw_addr); } static guint32 @@ -156,22 +145,20 @@ static gboolean match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hwaddr) { NMSettingWired *s_wired; - const GByteArray *mac; - const guint8 *device_mac; - guint device_mac_len; + const char *setting_mac; + const char *device_mac; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) return !fail_if_no_hwaddr; - mac = nm_setting_wired_get_mac_address (s_wired); - if (!mac) + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (!setting_mac) return !fail_if_no_hwaddr; - device_mac = nm_device_get_hw_address (device, &device_mac_len); + device_mac = nm_device_get_hw_address (device); - return ( mac->len == device_mac_len - && memcmp (mac->data, device_mac, device_mac_len) == 0); + return nm_utils_hwaddr_matches (setting_mac, -1, device_mac, -1); } static gboolean @@ -206,7 +193,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) * since both the parent interface and the VLAN ID matched by the time we * get here. */ - iface = nm_connection_get_virtual_iface_name (connection); + iface = nm_connection_get_interface_name (connection); if (iface) { if (g_strcmp0 (nm_device_get_ip_iface (device), iface) != 0) return FALSE; @@ -227,13 +214,14 @@ complete_connection (NMDevice *device, nm_utils_complete_generic (connection, NM_SETTING_VLAN_SETTING_NAME, existing_connections, - _("VLAN connection %d"), + NULL, + _("VLAN connection"), NULL, TRUE); s_vlan = nm_connection_get_setting_vlan (connection); if (!s_vlan) { - g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'vlan' setting is required."); return FALSE; } @@ -243,7 +231,7 @@ complete_connection (NMDevice *device, */ if ( !nm_setting_vlan_get_parent (s_vlan) && !match_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_VLAN_ERROR, NM_VLAN_ERROR_CONNECTION_INVALID, + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "The 'vlan' setting had no interface name, parent, or hardware address."); return FALSE; } @@ -280,6 +268,7 @@ nm_device_vlan_set_parent (NMDeviceVlan *device, NMDevice *parent) static void update_connection (NMDevice *device, NMConnection *connection) { + NMDeviceVlan *self = NM_DEVICE_VLAN (device); NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); int ifindex = nm_device_get_ifindex (device); @@ -290,12 +279,10 @@ update_connection (NMDevice *device, NMConnection *connection) if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new (); nm_connection_add_setting (connection, (NMSetting *) s_vlan); - g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, nm_device_get_iface (device), NULL); } if (!nm_platform_vlan_get_info (ifindex, &parent_ifindex, &vlan_id)) { - nm_log_warn (LOGD_VLAN, "(%s): failed to get VLAN interface info while updating connection.", - nm_device_get_iface (device)); + _LOGW (LOGD_VLAN, "failed to get VLAN interface info while updating connection."); return; } @@ -334,7 +321,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) NMConnection *connection; NMSettingVlan *s_vlan; NMSettingWired *s_wired; - const GByteArray *cloned_mac; + const char *cloned_mac; NMActStageReturn ret; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -353,8 +340,8 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (s_wired) { /* Set device MAC address if the connection wants to change it */ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_VLAN); + if (cloned_mac) + nm_device_set_hw_addr (dev, cloned_mac, "set", LOGD_VLAN); } s_vlan = nm_connection_get_setting_vlan (connection); @@ -392,7 +379,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) if (s_wired) { mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } } @@ -403,7 +390,8 @@ deactivate (NMDevice *device) NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_VLAN); } /******************************************************************/ @@ -421,89 +409,11 @@ parent_state_changed (NMDevice *parent, if (reason == NM_DEVICE_STATE_REASON_CARRIER) return; - if (new_state < NM_DEVICE_STATE_DISCONNECTED) { - /* If the parent becomes unavailable or unmanaged so does the VLAN */ - nm_device_state_changed (NM_DEVICE (self), new_state, reason); - } else if ( new_state == NM_DEVICE_STATE_DISCONNECTED - && old_state < NM_DEVICE_STATE_DISCONNECTED) { - /* Mark VLAN interface as available/disconnected when the parent - * becomes available as a result of becoming initialized. - */ - nm_device_state_changed (NM_DEVICE (self), new_state, reason); - } + nm_device_set_unmanaged (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason); } /******************************************************************/ -NMDevice * -nm_device_vlan_new (NMPlatformLink *platform_device, NMDevice *parent) -{ - NMDevice *device; - - g_return_val_if_fail (platform_device != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); - - device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_VLAN_PARENT, parent, - NM_DEVICE_DRIVER, "8021q", - NM_DEVICE_TYPE_DESC, "VLAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, - NULL); - if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { - g_object_unref (device); - device = NULL; - } - - return device; -} - -NMDevice * -nm_device_vlan_new_for_connection (NMConnection *connection, NMDevice *parent) -{ - NMDevice *device; - NMSettingVlan *s_vlan; - char *iface; - - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); - - s_vlan = nm_connection_get_setting_vlan (connection); - g_return_val_if_fail (s_vlan != NULL, NULL); - - iface = g_strdup (nm_connection_get_virtual_iface_name (connection)); - if (!iface) { - iface = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), - nm_setting_vlan_get_id (s_vlan)); - } - - if ( !nm_platform_vlan_add (iface, - nm_device_get_ifindex (parent), - nm_setting_vlan_get_id (s_vlan), - nm_setting_vlan_get_flags (s_vlan)) - && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { - nm_log_warn (LOGD_DEVICE | LOGD_VLAN, "(%s): failed to add VLAN interface for '%s'", - iface, nm_connection_get_id (connection)); - g_free (iface); - return NULL; - } - - device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_VLAN_PARENT, parent, - NM_DEVICE_DRIVER, "8021q", - NM_DEVICE_TYPE_DESC, "VLAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, - NULL); - g_free (iface); - if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { - g_object_unref (device); - device = NULL; - } - - return device; -} - static void nm_device_vlan_init (NMDeviceVlan * self) { @@ -512,10 +422,9 @@ nm_device_vlan_init (NMDeviceVlan * self) static void constructed (GObject *object) { - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - NMDevice *device = NM_DEVICE (object); - const char *iface = nm_device_get_iface (device); - int ifindex = nm_device_get_ifindex (device); + NMDeviceVlan *self = NM_DEVICE_VLAN (object); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); int parent_ifindex = -1, itype; int vlan_id; @@ -523,20 +432,20 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_device_vlan_parent_class)->constructed (object); if (!priv->parent) { - nm_log_err (LOGD_VLAN, "(%s): no parent specified.", iface); + _LOGE (LOGD_VLAN, "no parent specified."); priv->invalid = TRUE; return; } itype = nm_platform_link_get_type (ifindex); if (itype != NM_LINK_TYPE_VLAN) { - nm_log_err (LOGD_VLAN, "(%s): failed to get VLAN interface type.", iface); + _LOGE (LOGD_VLAN, "failed to get VLAN interface type."); priv->invalid = TRUE; return; } if (!nm_platform_vlan_get_info (ifindex, &parent_ifindex, &vlan_id)) { - nm_log_warn (LOGD_VLAN, "(%s): failed to get VLAN interface info.", iface); + _LOGW (LOGD_VLAN, "failed to get VLAN interface info."); priv->invalid = TRUE; return; } @@ -544,16 +453,15 @@ constructed (GObject *object) if ( parent_ifindex < 0 || parent_ifindex != nm_device_get_ip_ifindex (priv->parent) || vlan_id < 0) { - nm_log_warn (LOGD_VLAN, "(%s): VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", - iface, parent_ifindex, priv->vlan_id); + _LOGW (LOGD_VLAN, "VLAN parent ifindex (%d) or VLAN ID (%d) invalid.", + parent_ifindex, priv->vlan_id); priv->invalid = TRUE; return; } priv->vlan_id = vlan_id; - nm_log_dbg (LOGD_HW | LOGD_VLAN, "(%s): kernel ifindex %d", iface, ifindex); - nm_log_info (LOGD_HW | LOGD_VLAN, "(%s): VLAN ID %d with parent %s", - iface, priv->vlan_id, nm_device_get_iface (priv->parent)); + _LOGI (LOGD_HW | LOGD_VLAN, "VLAN ID %d with parent %s", + priv->vlan_id, nm_device_get_iface (priv->parent)); } static void @@ -563,6 +471,12 @@ get_property (GObject *object, guint prop_id, NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); switch (prop_id) { + case PROP_PARENT: + g_value_set_boxed (value, priv->parent ? nm_device_get_path (priv->parent) : "/"); + break; + case PROP_INT_PARENT_DEVICE: + g_value_set_object (value, priv->parent); + break; case PROP_VLAN_ID: g_value_set_uint (value, priv->vlan_id); break; @@ -579,7 +493,7 @@ set_property (GObject *object, guint prop_id, NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); switch (prop_id) { - case PROP_PARENT: + case PROP_INT_PARENT_DEVICE: nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), g_value_get_object (value)); break; case PROP_VLAN_ID: @@ -608,6 +522,17 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object); } +static void +finalize (GObject *object) +{ + NMDeviceVlan *self = NM_DEVICE_VLAN (object); + NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self); + + g_free (priv->initial_hw_addr); + + G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object); +} + static void nm_device_vlan_class_init (NMDeviceVlanClass *klass) { @@ -623,6 +548,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; + object_class->finalize = finalize; parent_class->update_initial_hw_address = update_initial_hw_address; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -638,22 +564,137 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_object (NM_DEVICE_VLAN_PARENT, - "Parent", - "Parent", - NM_TYPE_DEVICE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_boxed (NM_DEVICE_VLAN_PARENT, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_VLAN_ID, - g_param_spec_uint (NM_DEVICE_VLAN_ID, - "VLAN ID", - "VLAN ID", + g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "", 0, 4095, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + /* Internal properties */ + g_object_class_install_property + (object_class, PROP_INT_PARENT_DEVICE, + g_param_spec_object (NM_DEVICE_VLAN_INT_PARENT_DEVICE, "", "", + NM_TYPE_DEVICE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_vlan_object_info); +} + +/*************************************************************/ - dbus_g_error_domain_register (NM_VLAN_ERROR, NULL, NM_TYPE_VLAN_ERROR); +#define NM_TYPE_VLAN_FACTORY (nm_vlan_factory_get_type ()) +#define NM_VLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VLAN_FACTORY, NMVlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + int parent_ifindex = -1; + NMDevice *parent, *device; + + if (plink->type != NM_LINK_TYPE_VLAN) + return NULL; + + /* Have to find the parent device */ + if (!nm_platform_vlan_get_info (plink->ifindex, &parent_ifindex, NULL)) { + nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", plink->name); + return NULL; + } + + parent = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex); + if (!parent) { + /* If udev signaled the VLAN interface before it signaled + * the VLAN's parent at startup we may not know about the + * parent device yet. But we'll find it on the second pass + * from nm_manager_start(). + */ + nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", plink->name); + return NULL; + } + + device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent, + NM_DEVICE_DRIVER, "8021q", + NM_DEVICE_TYPE_DESC, "VLAN", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, + NULL); + if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { + g_object_unref (device); + device = NULL; + } + + /* Set initial parent-dependent unmanaged flag */ + if (device) + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent)); + + return device; } + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + NMDevice *device; + NMSettingVlan *s_vlan; + char *iface; + + if (!nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) + return NULL; + + g_return_val_if_fail (NM_IS_DEVICE (parent), NULL); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_return_val_if_fail (s_vlan != NULL, NULL); + + iface = g_strdup (nm_connection_get_interface_name (connection)); + if (!iface) { + iface = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), + nm_setting_vlan_get_id (s_vlan)); + } + + if ( !nm_platform_vlan_add (iface, + nm_device_get_ifindex (parent), + nm_setting_vlan_get_id (s_vlan), + nm_setting_vlan_get_flags (s_vlan)) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + nm_log_warn (LOGD_DEVICE | LOGD_VLAN, "(%s) failed to add VLAN interface for '%s'", + iface, nm_connection_get_id (connection)); + g_free (iface); + return NULL; + } + + device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN, + NM_DEVICE_IFACE, iface, + NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent, + NM_DEVICE_DRIVER, "8021q", + NM_DEVICE_TYPE_DESC, "VLAN", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN, + NULL); + g_free (iface); + if (NM_DEVICE_VLAN_GET_PRIVATE (device)->invalid) { + g_object_unref (device); + device = NULL; + } + + /* Set initial parent-dependent unmanaged flag */ + if (device) + nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent)); + + return device; +} + +DEFINE_DEVICE_FACTORY_INTERNAL(VLAN, Vlan, vlan, \ + factory_iface->new_link = new_link; \ + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + ) + diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h index 0f2ac70d..20fc3453 100644 --- a/src/devices/nm-device-vlan.h +++ b/src/devices/nm-device-vlan.h @@ -18,8 +18,8 @@ * Copyright 2012 Red Hat, Inc. */ -#ifndef NM_DEVICE_VLAN_H -#define NM_DEVICE_VLAN_H +#ifndef __NETWORKMANAGER_DEVICE_VLAN_H__ +#define __NETWORKMANAGER_DEVICE_VLAN_H__ #include @@ -40,26 +40,18 @@ typedef enum { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ } NMVlanError; +/* D-Bus exported properties */ #define NM_DEVICE_VLAN_PARENT "parent" #define NM_DEVICE_VLAN_ID "vlan-id" -typedef struct { - NMDevice parent; -} NMDeviceVlan; - -typedef struct { - NMDeviceClass parent; - -} NMDeviceVlanClass; +/* Internal non-exported properties */ +#define NM_DEVICE_VLAN_INT_PARENT_DEVICE "int-parent-device" +typedef NMDevice NMDeviceVlan; +typedef NMDeviceClass NMDeviceVlanClass; GType nm_device_vlan_get_type (void); -NMDevice *nm_device_vlan_new (NMPlatformLink *platform_link, - NMDevice *parent); -NMDevice *nm_device_vlan_new_for_connection (NMConnection *connection, - NMDevice *parent); - G_END_DECLS #endif /* NM_DEVICE_VLAN_H */ diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 0be57106..ed6b8fa0 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -29,9 +29,13 @@ #include "nm-manager.h" #include "nm-platform.h" #include "nm-utils.h" +#include "nm-device-factory.h" #include "nm-device-vxlan-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceVxlan); + G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_VXLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VXLAN, NMDeviceVxlanPrivate)) @@ -67,13 +71,13 @@ enum { static void update_properties (NMDevice *device) { + NMDeviceVxlan *self = NM_DEVICE_VXLAN (device); NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device); GObject *object = G_OBJECT (device); NMPlatformVxlanProperties props; if (!nm_platform_vxlan_get_properties (nm_device_get_ifindex (device), &props)) { - nm_log_warn (LOGD_HW, "(%s): could not read vxlan properties", - nm_device_get_iface (device)); + _LOGW (LOGD_HW, "could not read vxlan properties"); return; } @@ -130,18 +134,6 @@ link_changed (NMDevice *device, NMPlatformLink *info) /**************************************************************/ -NMDevice * -nm_device_vxlan_new (NMPlatformLink *platform_device) -{ - g_return_val_if_fail (platform_device != NULL, NULL); - - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN, - NM_DEVICE_PLATFORM_DEVICE, platform_device, - NM_DEVICE_TYPE_DESC, "Vxlan", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, - NULL); -} - static void nm_device_vxlan_init (NMDeviceVxlan *self) { @@ -240,133 +232,140 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_PARENT, - g_param_spec_boxed (NM_DEVICE_VXLAN_PARENT, - "Parent", - "Parent device", + g_param_spec_boxed (NM_DEVICE_VXLAN_PARENT, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ID, - g_param_spec_uint (NM_DEVICE_VXLAN_ID, - "Id", - "Id", + g_param_spec_uint (NM_DEVICE_VXLAN_ID, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_GROUP, - g_param_spec_string (NM_DEVICE_VXLAN_GROUP, - "Group", - "Group", + g_param_spec_string (NM_DEVICE_VXLAN_GROUP, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LOCAL, - g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, - "Local", - "Local", + g_param_spec_string (NM_DEVICE_VXLAN_LOCAL, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TOS, - g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, - "ToS", - "ToS", + g_param_spec_uchar (NM_DEVICE_VXLAN_TOS, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TTL, - g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, - "TTL", - "TTL", + g_param_spec_uchar (NM_DEVICE_VXLAN_TTL, "", "", 0, 255, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LEARNING, - g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, - "Learning", - "Learning", + g_param_spec_boolean (NM_DEVICE_VXLAN_LEARNING, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AGEING, - g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, - "Ageing", - "Ageing", + g_param_spec_uint (NM_DEVICE_VXLAN_AGEING, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_LIMIT, - g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, - "Limit", - "Limit", + g_param_spec_uint (NM_DEVICE_VXLAN_LIMIT, "", "", 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DST_PORT, - g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, - "Destination port", - "Destination port", + g_param_spec_uint (NM_DEVICE_VXLAN_DST_PORT, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SRC_PORT_MIN, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, - "Source port min", - "Minimum source port", + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MIN, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SRC_PORT_MAX, - g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, - "Source port max", - "Maximum source port", + g_param_spec_uint (NM_DEVICE_VXLAN_SRC_PORT_MAX, "", "", 0, 65535, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PROXY, - g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, - "Proxy", - "Proxy", + g_param_spec_boolean (NM_DEVICE_VXLAN_PROXY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSC, - g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, - "RSC", - "RSC", + g_param_spec_boolean (NM_DEVICE_VXLAN_RSC, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_L2MISS, - g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, - "L2miss", - "L2miss", + g_param_spec_boolean (NM_DEVICE_VXLAN_L2MISS, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_L3MISS, - g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, - "L3miss", - "L3miss", + g_param_spec_boolean (NM_DEVICE_VXLAN_L3MISS, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_vxlan_object_info); } + +/*************************************************************/ + +#define NM_TYPE_VXLAN_FACTORY (nm_vxlan_factory_get_type ()) +#define NM_VXLAN_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VXLAN_FACTORY, NMVxlanFactory)) + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_VXLAN) { + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_VXLAN, + NM_DEVICE_PLATFORM_DEVICE, plink, + NM_DEVICE_TYPE_DESC, "Vxlan", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_GENERIC, + NULL); + } + return NULL; +} + +DEFINE_DEVICE_FACTORY_INTERNAL_WITH_DEVTYPE(VXLAN, Vxlan, vxlan, GENERIC, \ + factory_iface->new_link = new_link; \ + ) + diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index 14b158de..cc6081e6 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -18,8 +18,8 @@ * Copyright 2013, 2014 Red Hat, Inc. */ -#ifndef NM_DEVICE_VXLAN_H -#define NM_DEVICE_VXLAN_H +#ifndef __NETWORKMANAGER_DEVICE_VXLAN_H__ +#define __NETWORKMANAGER_DEVICE_VXLAN_H__ #include @@ -51,19 +51,11 @@ G_BEGIN_DECLS #define NM_DEVICE_VXLAN_L2MISS "l2miss" #define NM_DEVICE_VXLAN_L3MISS "l3miss" -typedef struct { - NMDeviceGeneric parent; -} NMDeviceVxlan; - -typedef struct { - NMDeviceGenericClass parent; - -} NMDeviceVxlanClass; +typedef NMDeviceGeneric NMDeviceVxlan; +typedef NMDeviceGenericClass NMDeviceVxlanClass; GType nm_device_vxlan_get_type (void); -NMDevice *nm_device_vxlan_new (NMPlatformLink *platform_device); - G_END_DECLS #endif /* NM_DEVICE_VXLAN_H */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4788a604..a9899535 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -19,7 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -35,10 +36,9 @@ #include #include #include -#include #include -#include "libgsystem.h" +#include "gsystem-local-alloc.h" #include "nm-glib-compat.h" #include "nm-device.h" #include "nm-device-private.h" @@ -49,13 +49,13 @@ #include "nm-lndp-rdisc.h" #include "nm-dhcp-manager.h" #include "nm-dbus-manager.h" -#include "nm-utils.h" #include "nm-logging.h" -#include "nm-setting-ip4-config.h" -#include "nm-setting-ip6-config.h" -#include "nm-setting-connection.h" +#include "nm-activation-request.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-dnsmasq-manager.h" #include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" #include "nm-rfkill-manager.h" #include "nm-firewall-manager.h" #include "nm-properties-changed-signal.h" @@ -63,25 +63,23 @@ #include "nm-settings-connection.h" #include "nm-connection-provider.h" #include "nm-posix-signals.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-dbus-glib-types.h" #include "nm-dispatcher.h" -#include "nm-config-device.h" #include "nm-config.h" #include "nm-dns-manager.h" +#include "nm-core-internal.h" +#include "nm-default-route-manager.h" -#include "nm-device-bridge.h" -#include "nm-device-bond.h" -#include "nm-device-team.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF (NMDevice); -static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); +static void impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context); +static void impl_device_delete (NMDevice *self, DBusGMethodInvocation *context); #include "nm-device-glue.h" -static void nm_device_config_device_interface_init (NMConfigDeviceInterface *iface); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMDevice, nm_device, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (NM_TYPE_CONFIG_DEVICE, nm_device_config_device_interface_init)) +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, G_TYPE_OBJECT) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) @@ -176,6 +174,7 @@ typedef struct { typedef struct { gboolean in_state_changed; + gboolean initialized; NMDeviceState state; NMDeviceStateReason state_reason; @@ -199,7 +198,7 @@ typedef struct { RfKillType rfkill_type; gboolean firmware_missing; GHashTable * available_connections; - guint8 hw_addr[NM_UTILS_HWADDR_LEN_MAX]; + char * hw_addr; guint hw_addr_len; char * physical_port_id; @@ -230,22 +229,32 @@ typedef struct { guint carrier_wait_id; gboolean ignore_carrier; guint32 mtu; + gboolean up; /* IFF_UP */ /* Generic DHCP stuff */ guint32 dhcp_timeout; - GByteArray * dhcp_anycast_address; + char * dhcp_anycast_address; /* IP4 configuration info */ NMIP4Config * ip4_config; /* Combined config from VPN, settings, and device */ IpState ip4_state; NMIP4Config * dev_ip4_config; /* Config from DHCP, PPP, LLv4, etc */ NMIP4Config * ext_ip4_config; /* Stuff added outside NM */ + gboolean ext_ip4_config_had_any_addresses; + NMIP4Config * wwan_ip4_config; /* WWAN configuration */ + struct { + gboolean v4_has; + gboolean v4_is_assumed; + NMPlatformIP4Route v4; + gboolean v6_has; + gboolean v6_is_assumed; + NMPlatformIP6Route v6; + } default_route; /* DHCPv4 tracking */ - NMDHCPClient * dhcp4_client; + NMDhcpClient * dhcp4_client; gulong dhcp4_state_sigid; - gulong dhcp4_timeout_sigid; - NMDHCP4Config * dhcp4_config; + NMDhcp4Config * dhcp4_config; NMIP4Config * vpn4_config; /* routes added by a VPN which uses this device */ guint arp_round2_id; @@ -255,9 +264,8 @@ typedef struct { NMDnsMasqManager *dnsmasq_manager; gulong dnsmasq_state_id; - /* Firewall Manager */ - NMFirewallManager *fw_manager; - DBusGProxyCall *fw_call; + /* Firewall */ + NMFirewallPendingCall fw_call; /* avahi-autoipd stuff */ GPid aipd_pid; @@ -268,10 +276,14 @@ typedef struct { NMIP6Config * ip6_config; IpState ip6_state; NMIP6Config * vpn6_config; /* routes added by a VPN which uses this device */ + NMIP6Config * wwan_ip6_config; NMIP6Config * ext_ip6_config; /* Stuff added outside NM */ + gboolean ext_ip6_config_had_any_addresses; + gboolean nm_ipv6ll; /* TRUE if NM handles the device's IPv6LL address */ NMRDisc * rdisc; - gulong rdisc_config_changed_sigid; + gulong rdisc_changed_id; + gulong rdisc_timeout_id; NMSettingIP6ConfigPrivacy rdisc_use_tempaddr; /* IP6 config from autoconf */ NMIP6Config * ac_ip6_config; @@ -280,11 +292,10 @@ typedef struct { GHashTable * ip6_saved_properties; - NMDHCPClient * dhcp6_client; + NMDhcpClient * dhcp6_client; NMRDiscDHCPLevel dhcp6_mode; gulong dhcp6_state_sigid; - gulong dhcp6_timeout_sigid; - NMDHCP6Config * dhcp6_config; + NMDhcp6Config * dhcp6_config; /* IP6 config from DHCP */ NMIP6Config * dhcp6_ip6_config; @@ -303,8 +314,9 @@ typedef struct { NMConnectionProvider *con_provider; } NMDevicePrivate; -static gboolean nm_device_set_ip4_config (NMDevice *dev, +static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, + guint32 default_route_metric, gboolean commit, NMDeviceStateReason *reason); static gboolean ip4_config_merge_and_apply (NMDevice *self, @@ -312,36 +324,27 @@ static gboolean ip4_config_merge_and_apply (NMDevice *self, gboolean commit, NMDeviceStateReason *out_reason); -static gboolean nm_device_set_ip6_config (NMDevice *dev, +static gboolean nm_device_set_ip6_config (NMDevice *self, NMIP6Config *config, gboolean commit, NMDeviceStateReason *reason); -static gboolean nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure); -static void nm_device_slave_notify_enslave (NMDevice *dev, gboolean success); -static void nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason); +static gboolean nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure); +static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success); +static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason); -static void addrconf6_start_with_link_ready (NMDevice *self); +static gboolean addrconf6_start_with_link_ready (NMDevice *self); +static gboolean dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection); +static NMActStageReturn linklocal6_start (NMDevice *self); -static gboolean nm_device_get_default_unmanaged (NMDevice *device); +static gboolean nm_device_get_default_unmanaged (NMDevice *self); -static void _set_state_full (NMDevice *device, +static void _set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting); -/***********************************************************/ - -static GQuark -nm_device_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-device-error"); - return quark; -} - -#define NM_DEVICE_ERROR (nm_device_error_quark ()) +static void nm_device_update_hw_address (NMDevice *self); /***********************************************************/ @@ -366,7 +369,7 @@ static const char *state_table[] = { static const char * queued_state_to_string (NMDeviceState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return state_table[NM_DEVICE_STATE_UNKNOWN]; } @@ -442,41 +445,41 @@ static const char *reason_table[] = { static const char * reason_to_string (NMDeviceStateReason reason) { - if (reason >= 0 && reason < G_N_ELEMENTS (reason_table)) + if ((gsize) reason < G_N_ELEMENTS (reason_table)) return reason_table[reason]; return reason_table[NM_DEVICE_STATE_REASON_UNKNOWN]; } /***********************************************************/ -static inline gboolean +gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value) { return nm_platform_sysctl_set (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value); } static gboolean -device_has_capability (NMDevice *device, NMDeviceCapabilities caps) +device_has_capability (NMDevice *self, NMDeviceCapabilities caps) { - return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & caps); + return !!(NM_DEVICE_GET_PRIVATE (self)->capabilities & caps); } /***********************************************************/ void -nm_device_dbus_export (NMDevice *device) +nm_device_dbus_export (NMDevice *self) { static guint32 devcount = 0; NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->path == NULL); priv->path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++); - nm_log_info (LOGD_DEVICE, "(%s): exported as %s", priv->iface, priv->path); - nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, device); + _LOGI (LOGD_DEVICE, "exported as %s", priv->path); + nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, self); } const char * @@ -498,7 +501,7 @@ nm_device_get_udi (NMDevice *self) const char * nm_device_get_iface (NMDevice *self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_DEVICE (self), 0); return NM_DEVICE_GET_PRIVATE (self)->iface; } @@ -512,9 +515,9 @@ nm_device_get_ifindex (NMDevice *self) } gboolean -nm_device_is_software (NMDevice *device) +nm_device_is_software (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return priv->is_software; } @@ -562,11 +565,14 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) if (priv->ip_iface) { priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface); if (priv->ip_ifindex > 0) { + if (nm_platform_check_support_user_ipv6ll ()) + nm_platform_link_set_user_ipv6ll_enabled (priv->ip_ifindex, TRUE); + if (!nm_platform_link_is_up (priv->ip_ifindex)) nm_platform_link_set_up (priv->ip_ifindex); } else { /* Device IP interface must always be a kernel network interface */ - nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", iface); + _LOGW (LOGD_HW, "failed to look up interface index"); } } @@ -579,6 +585,43 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) g_free (old_ip_iface); } +static gboolean +get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) +{ + NMLinkType link_type; + const guint8 *hwaddr = NULL; + size_t hwaddr_len = 0; + 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); + + link_type = nm_platform_link_get_type (ifindex); + g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0); + + hwaddr = nm_platform_link_get_address (ifindex, &hwaddr_len); + if (!hwaddr_len) + return FALSE; + + success = nm_utils_get_ipv6_interface_identifier (link_type, + hwaddr, + hwaddr_len, + out_iid); + if (!success) { + _LOGW (LOGD_HW, "failed to generate interface identifier " + "for link type %u hwaddr_len %zu", link_type, hwaddr_len); + } + return success; +} + +static gboolean +nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid) +{ + return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); +} + const char * nm_device_get_driver (NMDevice *self) { @@ -606,54 +649,124 @@ nm_device_get_device_type (NMDevice *self) /** * nm_device_get_priority(): - * @dev: the #NMDevice + * @self: the #NMDevice * * Returns: the device's routing priority. Lower numbers means a "better" * device, eg higher priority. */ int -nm_device_get_priority (NMDevice *dev) +nm_device_get_priority (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (dev), 100); + g_return_val_if_fail (NM_IS_DEVICE (self), 1000); - /* Device 'priority' is used for two things: + /* Device 'priority' is used for the default route-metric and is based on + * the device type. The settings ipv4.route-metric and ipv6.route-metric + * can overwrite this default. + * + * Currently for both IPv4 and IPv6 we use the same default values. * - * a) two devices on the same IP subnet: the "better" (ie, lower number) - * device is the default outgoing device for that subnet - * b) default route: the "better" device gets the default route. This can - * always be modified by setting a connection to never-default=TRUE, in - * which case that device will never take the default route when - * it's using that connection. + * The route-metric is used for the metric of the routes of device. + * This also applies to the default route. Therefore it affects also + * which device is the "best". + * + * For comparison, note that iproute2 by default adds IPv4 routes with + * metric 0, and IPv6 routes with metric 1024. The latter is the IPv6 + * "user default" in the kernel (NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6). + * In kernel, the full uint32_t range is available for route + * metrics (except for IPv6, where 0 means 1024). */ - switch (nm_device_get_device_type (dev)) { + switch (nm_device_get_device_type (self)) { + /* 50 is reserved for VPN (NM_VPN_ROUTE_METRIC_DEFAULT) */ case NM_DEVICE_TYPE_ETHERNET: - return 1; + return 100; case NM_DEVICE_TYPE_INFINIBAND: - return 2; + return 150; case NM_DEVICE_TYPE_ADSL: - return 3; + return 200; case NM_DEVICE_TYPE_WIMAX: - return 4; + return 250; case NM_DEVICE_TYPE_BOND: - return 5; + return 300; case NM_DEVICE_TYPE_TEAM: - return 6; + return 350; case NM_DEVICE_TYPE_VLAN: - return 7; + return 400; case NM_DEVICE_TYPE_MODEM: - return 8; + return 450; case NM_DEVICE_TYPE_BT: - return 9; + return 550; case NM_DEVICE_TYPE_WIFI: - return 10; + return 600; case NM_DEVICE_TYPE_OLPC_MESH: - return 11; + return 650; default: - return 20; + return 950; } } +guint32 +nm_device_get_ip4_route_metric (NMDevice *self) +{ + NMConnection *connection; + gint64 route_metric = -1; + + g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); + + connection = nm_device_get_connection (self); + + if (connection) + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (connection)); + + return route_metric >= 0 ? route_metric : nm_device_get_priority (self); +} + +guint32 +nm_device_get_ip6_route_metric (NMDevice *self) +{ + NMConnection *connection; + gint64 route_metric = -1; + + g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); + + connection = nm_device_get_connection (self); + + if (connection) + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (connection)); + + return route_metric >= 0 ? route_metric : nm_device_get_priority (self); +} + +const NMPlatformIP4Route * +nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (out_is_assumed) + *out_is_assumed = priv->default_route.v4_is_assumed; + + return priv->default_route.v4_has ? &priv->default_route.v4 : NULL; +} + +const NMPlatformIP6Route * +nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); + + if (out_is_assumed) + *out_is_assumed = priv->default_route.v6_is_assumed; + + return priv->default_route.v6_has ? &priv->default_route.v6 : NULL; +} + const char * nm_device_get_type_desc (NMDevice *self) { @@ -663,9 +776,9 @@ nm_device_get_type_desc (NMDevice *self) } gboolean -nm_device_has_carrier (NMDevice *device) +nm_device_has_carrier (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->carrier; + return NM_DEVICE_GET_PRIVATE (self)->carrier; } NMActRequest * @@ -693,22 +806,38 @@ nm_device_get_rfkill_type (NMDevice *self) } static const char * -nm_device_get_physical_port_id (NMDevice *device) +nm_device_get_physical_port_id (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->physical_port_id; + return NM_DEVICE_GET_PRIVATE (self)->physical_port_id; } /***********************************************************/ static gboolean -nm_device_uses_generated_connection (NMDevice *self) +nm_device_uses_generated_assumed_connection (NMDevice *self) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - connection = nm_device_get_connection (self); - if (!connection) - return FALSE; - return nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (connection)); + if ( priv->act_request + && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) { + connection = nm_act_request_get_connection (priv->act_request); + if ( connection + && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + return TRUE; + } + return FALSE; +} + +gboolean +nm_device_uses_assumed_connection (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if ( priv->act_request + && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) + return TRUE; + return FALSE; } static SlaveInfo * @@ -737,28 +866,28 @@ free_slave_info (SlaveInfo *info) /** * nm_device_enslave_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to enslave * @connection: (allow-none): the slave device's connection * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function enslaves @slave. * * Returns: %TRUE on success, %FALSE on failure or if this device cannot enslave * other devices. */ static gboolean -nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connection) +nm_device_enslave_slave (NMDevice *self, NMDevice *slave, NMConnection *connection) { SlaveInfo *info; gboolean success = FALSE; gboolean configure; - g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->enslave_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); - info = find_slave_info (dev, slave); + info = find_slave_info (self, slave); if (!info) return FALSE; @@ -769,7 +898,7 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio if (configure) g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - success = NM_DEVICE_GET_CLASS (dev)->enslave_slave (dev, slave, connection, configure); + success = NM_DEVICE_GET_CLASS (self)->enslave_slave (self, slave, connection, configure); info->enslaved = success; } @@ -778,18 +907,18 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio /* Ensure the device's hardware address is up-to-date; it often changes * when slaves change. */ - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); /* Restart IP configuration if we're waiting for slaves. Do this * after updating the hardware address as IP config may need the * new address. */ if (success) { - if (NM_DEVICE_GET_PRIVATE (dev)->ip4_state == IP_WAIT) - nm_device_activate_stage3_ip4_start (dev); + if (NM_DEVICE_GET_PRIVATE (self)->ip4_state == IP_WAIT) + nm_device_activate_stage3_ip4_start (self); - if (NM_DEVICE_GET_PRIVATE (dev)->ip6_state == IP_WAIT) - nm_device_activate_stage3_ip6_start (dev); + if (NM_DEVICE_GET_PRIVATE (self)->ip6_state == IP_WAIT) + nm_device_activate_stage3_ip6_start (self); } return success; @@ -797,42 +926,42 @@ nm_device_enslave_slave (NMDevice *dev, NMDevice *slave, NMConnection *connectio /** * nm_device_release_one_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to release - * @configure: whether @dev needs to actually release @slave + * @configure: whether @self needs to actually release @slave * @reason: the state change reason for the @slave * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function releases the previously enslaved @slave and/or - * updates the state of @dev and @slave to reflect its release. + * updates the state of @self and @slave to reflect its release. * * Returns: %TRUE on success, %FALSE on failure, if this device cannot enslave * other devices, or if @slave was never enslaved. */ static gboolean -nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure, NMDeviceStateReason reason) +nm_device_release_one_slave (NMDevice *self, NMDevice *slave, gboolean configure, NMDeviceStateReason reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); SlaveInfo *info; gboolean success = FALSE; g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->release_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->release_slave != NULL, FALSE); - info = find_slave_info (dev, slave); + info = find_slave_info (self, slave); if (!info) return FALSE; priv->slaves = g_slist_remove (priv->slaves, info); if (info->enslaved) { - success = NM_DEVICE_GET_CLASS (dev)->release_slave (dev, slave, configure); + success = NM_DEVICE_GET_CLASS (self)->release_slave (self, slave, configure); /* The release_slave() implementation logs success/failure (in the * correct device-specific log domain), so we don't have to do anything. */ } if (!configure) { - g_warn_if_fail (reason == NM_DEVICE_STATE_REASON_NONE); + g_warn_if_fail (reason == NM_DEVICE_STATE_REASON_NONE || reason == NM_DEVICE_STATE_REASON_REMOVED); reason = NM_DEVICE_STATE_REASON_NONE; } else if (reason == NM_DEVICE_STATE_REASON_NONE) { g_warn_if_reached (); @@ -845,20 +974,53 @@ nm_device_release_one_slave (NMDevice *dev, NMDevice *slave, gboolean configure, /* Ensure the device's hardware address is up-to-date; it often changes * when slaves change. */ - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); return success; } +static gboolean +is_software_external (NMDevice *self) +{ + return nm_device_is_software (self) + && !nm_device_get_is_nm_owned (self); +} + +/** + * nm_device_finish_init: + * @self: the master device + * + * Whatever needs to be done post-initialization, when the device has a DBus + * object name. + */ +void +nm_device_finish_init (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + g_assert (priv->initialized == FALSE); + + /* Do not manage externally created software devices until they are IFF_UP */ + if ( is_software_external (self) + && !nm_platform_link_is_up (priv->ifindex) + && priv->ifindex > 0) + nm_device_set_initial_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN, TRUE); + + if (priv->master) + nm_device_enslave_slave (priv->master, self, NULL); + + priv->initialized = TRUE; +} + static void -carrier_changed (NMDevice *device, gboolean carrier) +carrier_changed (NMDevice *self, gboolean carrier) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!nm_device_get_managed (device)) + if (!nm_device_get_managed (self)) return; - nm_device_recheck_available_connections (device); + nm_device_recheck_available_connections (self); /* ignore-carrier devices ignore all carrier-down events */ if (priv->ignore_carrier && !carrier) @@ -872,13 +1034,13 @@ carrier_changed (NMDevice *device, gboolean carrier) if (!carrier) return; - if (nm_device_activate_ip4_state_in_wait (device)) - nm_device_activate_stage3_ip4_start (device); - if (nm_device_activate_ip6_state_in_wait (device)) - nm_device_activate_stage3_ip6_start (device); + if (nm_device_activate_ip4_state_in_wait (self)) + nm_device_activate_stage3_ip4_start (self); + if (nm_device_activate_ip6_state_in_wait (self)) + nm_device_activate_stage3_ip6_start (self); return; - } else if (nm_device_get_enslaved (device) && !carrier) { + } else if (nm_device_get_enslaved (self) && !carrier) { /* Slaves don't deactivate when they lose carrier; for * bonds/teams in particular that would be actively * counterproductive. @@ -890,7 +1052,7 @@ carrier_changed (NMDevice *device, gboolean carrier) g_warn_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE); if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); } else if (priv->state == NM_DEVICE_STATE_DISCONNECTED) { /* If the device is already in DISCONNECTED state without a carrier @@ -898,14 +1060,16 @@ carrier_changed (NMDevice *device, gboolean carrier) * when the carrier appears, auto connections are rechecked for * the device. */ - nm_device_emit_recheck_auto_activate (device); + nm_device_emit_recheck_auto_activate (self); } } else { + g_return_if_fail (priv->state >= NM_DEVICE_STATE_UNAVAILABLE); + if (priv->state == NM_DEVICE_STATE_UNAVAILABLE) { - if (nm_device_queued_state_peek (device) >= NM_DEVICE_STATE_DISCONNECTED) - nm_device_queued_state_clear (device); - } else if (priv->state >= NM_DEVICE_STATE_DISCONNECTED) { - nm_device_queue_state (device, NM_DEVICE_STATE_UNAVAILABLE, + if (nm_device_queued_state_peek (self) >= NM_DEVICE_STATE_DISCONNECTED) + nm_device_queued_state_clear (self); + } else { + nm_device_queue_state (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CARRIER); } } @@ -916,18 +1080,16 @@ carrier_changed (NMDevice *device, gboolean carrier) static gboolean link_disconnect_action_cb (gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (calling deferred action) (id=%u)", - nm_device_get_iface (device), priv->carrier_defer_id); + _LOGD (LOGD_DEVICE, "link disconnected (calling deferred action) (id=%u)", priv->carrier_defer_id); priv->carrier_defer_id = 0; - nm_log_info (LOGD_DEVICE, "(%s): link disconnected (calling deferred action)", - nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE, "link disconnected (calling deferred action)"); - NM_DEVICE_GET_CLASS (device)->carrier_changed (device, FALSE); + NM_DEVICE_GET_CLASS (self)->carrier_changed (self, FALSE); return FALSE; } @@ -939,67 +1101,64 @@ link_disconnect_action_cancel (NMDevice *self) if (priv->carrier_defer_id) { g_source_remove (priv->carrier_defer_id); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (canceling deferred action) (id=%u)", - nm_device_get_iface (self), priv->carrier_defer_id); + _LOGD (LOGD_DEVICE, "link disconnected (canceling deferred action) (id=%u)", priv->carrier_defer_id); priv->carrier_defer_id = 0; } } void -nm_device_set_carrier (NMDevice *device, gboolean carrier) +nm_device_set_carrier (NMDevice *self, gboolean carrier) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDeviceState state = nm_device_get_state (device); - const char *iface = nm_device_get_iface (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDeviceState state = nm_device_get_state (self); if (priv->carrier == carrier) return; priv->carrier = carrier; - g_object_notify (G_OBJECT (device), NM_DEVICE_CARRIER); + g_object_notify (G_OBJECT (self), NM_DEVICE_CARRIER); if (priv->carrier) { - nm_log_info (LOGD_DEVICE, "(%s): link connected", iface); - link_disconnect_action_cancel (device); - klass->carrier_changed (device, TRUE); + _LOGI (LOGD_DEVICE, "link connected"); + link_disconnect_action_cancel (self); + klass->carrier_changed (self, TRUE); if (priv->carrier_wait_id) { g_source_remove (priv->carrier_wait_id); priv->carrier_wait_id = 0; - nm_device_remove_pending_action (device, "carrier wait", TRUE); + nm_device_remove_pending_action (self, "carrier wait", TRUE); } } else if (state <= NM_DEVICE_STATE_DISCONNECTED) { - nm_log_info (LOGD_DEVICE, "(%s): link disconnected", iface); - klass->carrier_changed (device, FALSE); + _LOGI (LOGD_DEVICE, "link disconnected"); + klass->carrier_changed (self, FALSE); } else { - nm_log_info (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds)", - iface, LINK_DISCONNECT_DELAY); + _LOGI (LOGD_DEVICE, "link disconnected (deferring action for %d seconds)", LINK_DISCONNECT_DELAY); priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY, - link_disconnect_action_cb, device); - nm_log_dbg (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds) (id=%u)", - iface, LINK_DISCONNECT_DELAY, priv->carrier_defer_id); + link_disconnect_action_cb, self); + _LOGD (LOGD_DEVICE, "link disconnected (deferring action for %d seconds) (id=%u)", + LINK_DISCONNECT_DELAY, priv->carrier_defer_id); } } static void -update_for_ip_ifname_change (NMDevice *device) +update_for_ip_ifname_change (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_hash_table_remove_all (priv->ip6_saved_properties); if (priv->dhcp4_client) { - if (!nm_device_dhcp4_renew (device, FALSE)) { - nm_device_state_changed (device, + if (!nm_device_dhcp4_renew (self, FALSE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); return; } } if (priv->dhcp6_client) { - if (!nm_device_dhcp6_renew (device, FALSE)) { - nm_device_state_changed (device, + if (!nm_device_dhcp6_renew (self, FALSE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); return; @@ -1014,98 +1173,152 @@ update_for_ip_ifname_change (NMDevice *device) } static void -device_link_changed (NMDevice *device, NMPlatformLink *info) +device_set_master (NMDevice *self, int ifindex) +{ + NMDevice *master; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + master = nm_manager_get_device_by_ifindex (nm_manager_get (), ifindex); + if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) { + g_clear_object (&priv->master); + priv->master = g_object_ref (master); + nm_device_master_add_slave (master, self, FALSE); + } else if (master) { + _LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring", + nm_device_get_iface (master)); + } else { + _LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s", + ifindex, + nm_platform_link_get_name (ifindex)); + } +} + +static void +device_link_changed (NMDevice *self, NMPlatformLink *info) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean ip_ifname_changed = FALSE; if (info->udi && g_strcmp0 (info->udi, priv->udi)) { /* Update UDI to what udev gives us */ g_free (priv->udi); priv->udi = g_strdup (info->udi); - g_object_notify (G_OBJECT (device), NM_DEVICE_UDI); + g_object_notify (G_OBJECT (self), NM_DEVICE_UDI); } /* Update MTU if it has changed. */ if (priv->mtu != info->mtu) { priv->mtu = info->mtu; - g_object_notify (G_OBJECT (device), NM_DEVICE_MTU); + g_object_notify (G_OBJECT (self), NM_DEVICE_MTU); } if (info->name[0] && strcmp (priv->iface, info->name) != 0) { - nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed iface from '%s' to '%s'", - priv->iface, priv->ifindex, priv->iface, info->name); + _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'", + priv->ifindex, priv->iface, info->name); g_free (priv->iface); priv->iface = g_strdup (info->name); /* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */ ip_ifname_changed = !priv->ip_iface; - g_object_notify (G_OBJECT (device), NM_DEVICE_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IFACE); if (ip_ifname_changed) - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); /* Re-match available connections against the new interface name */ - nm_device_recheck_available_connections (device); + nm_device_recheck_available_connections (self); /* Let any connections that use the new interface name have a chance * to auto-activate on the device. */ - nm_device_emit_recheck_auto_activate (device); + nm_device_emit_recheck_auto_activate (self); } /* Update slave status for external changes */ + if (priv->enslaved && info->master != nm_device_get_ifindex (priv->master)) + nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_NONE); if (info->master && !priv->enslaved) { - NMDevice *master; - - master = nm_manager_get_device_by_ifindex (nm_manager_get (), info->master); - if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave) { - g_clear_object (&priv->master); - priv->master = g_object_ref (master); - nm_device_master_add_slave (master, device, FALSE); - nm_device_enslave_slave (master, device, NULL); - } else if (master) { - nm_log_info (LOGD_DEVICE, "(%s): enslaved to non-master-type device %s; ignoring", - nm_device_get_iface (device), - nm_device_get_iface (master)); - } else { - nm_log_warn (LOGD_DEVICE, "(%s): enslaved to unknown device %d %s", - nm_device_get_iface (device), - info->master, - nm_platform_link_get_name (info->master)); - } - } else if (priv->enslaved && !info->master) - nm_device_release_one_slave (priv->master, device, FALSE, NM_DEVICE_STATE_REASON_NONE); + device_set_master (self, info->master); + if (priv->master) + nm_device_enslave_slave (priv->master, self, NULL); + } if (klass->link_changed) - klass->link_changed (device, info); - + klass->link_changed (self, info); /* Update DHCP, etc, if needed */ if (ip_ifname_changed) - update_for_ip_ifname_change (device); + update_for_ip_ifname_change (self); + + if (priv->up != info->up) { + priv->up = info->up; + + /* Manage externally-created software interfaces only when they are IFF_UP */ + g_assert (priv->ifindex > 0); + if (is_software_external (self)) { + gboolean external_down = nm_device_get_unmanaged_flag (self, NM_UNMANAGED_EXTERNAL_DOWN); + + if (external_down && info->up) { + if (nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED) { + /* Ensure the assume check is queued before any queued state changes + * from the transition to UNAVAILABLE. + */ + nm_device_queue_recheck_assume (self); + + /* Resetting the EXTERNAL_DOWN flag may change the device's state + * to UNAVAILABLE. To ensure that the state change doesn't touch + * the device before assumption occurs, pass + * NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED as the reason. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + FALSE, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + } else { + /* Don't trigger a state change; if the device is in a + * state higher than UNAVAILABLE, it is already IFF_UP + * or an explicit activation request was received. + */ + priv->unmanaged_flags &= ~NM_UNMANAGED_EXTERNAL_DOWN; + } + } else if (!external_down && !info->up && nm_device_get_state (self) <= NM_DEVICE_STATE_DISCONNECTED) { + /* If the device is already disconnected and is set !IFF_UP, + * unmanage it. + */ + nm_device_set_unmanaged (self, + NM_UNMANAGED_EXTERNAL_DOWN, + TRUE, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + } + } + } } static void -device_ip_link_changed (NMDevice *device, NMPlatformLink *info) +device_ip_link_changed (NMDevice *self, NMPlatformLink *info) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (info->name[0] && g_strcmp0 (priv->ip_iface, info->name)) { - nm_log_info (LOGD_DEVICE, "(%s): interface index %d renamed ip_iface (%d) from '%s' to '%s'", - priv->iface, priv->ifindex, nm_device_get_ip_ifindex (device), - priv->ip_iface, info->name); + _LOGI (LOGD_DEVICE, "interface index %d renamed ip_iface (%d) from '%s' to '%s'", + priv->ifindex, nm_device_get_ip_ifindex (self), + priv->ip_iface, info->name); g_free (priv->ip_iface); priv->ip_iface = g_strdup (info->name); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); - update_for_ip_ifname_change (device); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + update_for_ip_ifname_change (self); } } static void -link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlatformSignalChangeType change_type, NMPlatformReason reason, NMDevice *device) +link_changed_cb (NMPlatform *platform, + int ifindex, + NMPlatformLink *info, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDevice *self) { if (change_type != NM_PLATFORM_SIGNAL_CHANGED) return; @@ -1116,24 +1329,24 @@ link_changed_cb (NMPlatform *platform, int ifindex, NMPlatformLink *info, NMPlat * and it results in also setting IFF_LOWER_UP. */ - if (ifindex == nm_device_get_ifindex (device)) - device_link_changed (device, info); - else if (ifindex == nm_device_get_ip_ifindex (device)) - device_ip_link_changed (device, info); + if (ifindex == nm_device_get_ifindex (self)) + device_link_changed (self, info); + else if (ifindex == nm_device_get_ip_ifindex (self)) + device_ip_link_changed (self, info); } static void -link_changed (NMDevice *device, NMPlatformLink *info) +link_changed (NMDevice *self, NMPlatformLink *info) { /* Update carrier from link event if applicable. */ - if ( device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT) - && !device_has_capability (device, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) - nm_device_set_carrier (device, info->connected); + if ( device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT) + && !device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) + nm_device_set_carrier (self, info->connected); } /** * nm_device_notify_component_added(): - * @device: the #NMDevice + * @self: the #NMDevice * @component: the component being added by a plugin * * Called by the manager to notify the device that a new component has @@ -1144,16 +1357,16 @@ link_changed (NMDevice *device, NMPlatformLink *info) * claimed. */ gboolean -nm_device_notify_component_added (NMDevice *device, GObject *component) +nm_device_notify_component_added (NMDevice *self, GObject *component) { - if (NM_DEVICE_GET_CLASS (device)->component_added) - return NM_DEVICE_GET_CLASS (device)->component_added (device, component); + if (NM_DEVICE_GET_CLASS (self)->component_added) + return NM_DEVICE_GET_CLASS (self)->component_added (self, component); return FALSE; } /** * nm_device_owns_iface(): - * @device: the #NMDevice + * @self: the #NMDevice * @iface: an interface name * * Called by the manager to ask if the device or any of its components owns @@ -1162,17 +1375,25 @@ nm_device_notify_component_added (NMDevice *device, GObject *component) * because that ethernet interface is controlled by the WWAN device and cannot * be used independently of the WWAN device. * - * Returns: %TRUE if @device or it's components owns the interface name, + * Returns: %TRUE if @self or it's components owns the interface name, * %FALSE if not */ gboolean -nm_device_owns_iface (NMDevice *device, const char *iface) +nm_device_owns_iface (NMDevice *self, const char *iface) { - if (NM_DEVICE_GET_CLASS (device)->owns_iface) - return NM_DEVICE_GET_CLASS (device)->owns_iface (device, iface); + if (NM_DEVICE_GET_CLASS (self)->owns_iface) + return NM_DEVICE_GET_CLASS (self)->owns_iface (self, iface); return FALSE; } +NMConnection * +nm_device_new_default_connection (NMDevice *self) +{ + if (NM_DEVICE_GET_CLASS (self)->new_default_connection) + return NM_DEVICE_GET_CLASS (self)->new_default_connection (self); + return NULL; +} + static void slave_state_changed (NMDevice *slave, NMDeviceState slave_new_state, @@ -1183,13 +1404,12 @@ slave_state_changed (NMDevice *slave, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean release = FALSE; - nm_log_dbg (LOGD_DEVICE, "(%s): slave %s state change %d (%s) -> %d (%s)", - nm_device_get_iface (self), - nm_device_get_iface (slave), - slave_old_state, - state_to_string (slave_old_state), - slave_new_state, - state_to_string (slave_new_state)); + _LOGD (LOGD_DEVICE, "slave %s state change %d (%s) -> %d (%s)", + nm_device_get_iface (slave), + slave_old_state, + state_to_string (slave_old_state), + slave_new_state, + state_to_string (slave_new_state)); /* Don't try to enslave slaves until the master is ready */ if (priv->state < NM_DEVICE_STATE_CONFIG) @@ -1208,46 +1428,45 @@ slave_state_changed (NMDevice *slave, if (release) { nm_device_release_one_slave (self, slave, TRUE, reason); /* Bridge/bond/team interfaces are left up until manually deactivated */ - if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED) { - nm_log_dbg (LOGD_DEVICE, "(%s): last slave removed; remaining activated", - nm_device_get_iface (self)); - } + if (priv->slaves == NULL && priv->state == NM_DEVICE_STATE_ACTIVATED) + _LOGD (LOGD_DEVICE, "last slave removed; remaining activated"); } } /** * nm_device_master_add_slave: - * @dev: the master device + * @self: the master device * @slave: the slave device to enslave * @configure: pass %TRUE if the slave should be configured by the master, or * %FALSE if it is already configured outside NetworkManager * - * If @dev is capable of enslaving other devices (ie it's a bridge, bond, team, + * If @self is capable of enslaving other devices (ie it's a bridge, bond, team, * etc) then this function adds @slave to the slave list for later enslavement. * * Returns: %TRUE on success, %FALSE on failure */ static gboolean -nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure) +nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); SlaveInfo *info; - g_return_val_if_fail (dev != NULL, FALSE); + g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (slave != NULL, FALSE); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (dev)->enslave_slave != NULL, FALSE); + g_return_val_if_fail (NM_DEVICE_GET_CLASS (self)->enslave_slave != NULL, FALSE); if (configure) g_return_val_if_fail (nm_device_get_state (slave) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); - if (!find_slave_info (dev, slave)) { + if (!find_slave_info (self, slave)) { info = g_malloc0 (sizeof (SlaveInfo)); info->slave = g_object_ref (slave); info->configure = configure; info->watch_id = g_signal_connect (slave, "state-changed", - G_CALLBACK (slave_state_changed), dev); + G_CALLBACK (slave_state_changed), self); priv->slaves = g_slist_append (priv->slaves, info); } + nm_device_queue_recheck_assume (self); return TRUE; } @@ -1255,14 +1474,14 @@ nm_device_master_add_slave (NMDevice *dev, NMDevice *slave, gboolean configure) /** * nm_device_master_get_slaves: - * @dev: the master device + * @self: the master device * - * Returns: any slaves of which @device is the master. Caller owns returned list. + * Returns: any slaves of which @self is the master. Caller owns returned list. */ GSList * -nm_device_master_get_slaves (NMDevice *dev) +nm_device_master_get_slaves (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *slaves = NULL, *iter; for (iter = priv->slaves; iter; iter = g_slist_next (iter)) @@ -1273,18 +1492,18 @@ nm_device_master_get_slaves (NMDevice *dev) /** * nm_device_master_get_slave_by_ifindex: - * @dev: the master device + * @self: the master device * @ifindex: the slave's interface index * - * Returns: the slave with the given @ifindex of which @device is the master, - * or %NULL if no device with @ifindex is a slave of @device. + * Returns: the slave with the given @ifindex of which @self is the master, + * or %NULL if no device with @ifindex is a slave of @self. */ NMDevice * -nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex) +nm_device_master_get_slave_by_ifindex (NMDevice *self, int ifindex) { GSList *iter; - for (iter = NM_DEVICE_GET_PRIVATE (dev)->slaves; iter; iter = g_slist_next (iter)) { + for (iter = NM_DEVICE_GET_PRIVATE (self)->slaves; iter; iter = g_slist_next (iter)) { SlaveInfo *info = iter->data; if (nm_device_get_ip_ifindex (info->slave) == ifindex) @@ -1295,18 +1514,18 @@ nm_device_master_get_slave_by_ifindex (NMDevice *dev, int ifindex) /** * nm_device_master_check_slave_physical_port: - * @dev: the master device + * @self: the master device * @slave: a slave device * @log_domain: domain to log a warning in * - * Checks if @dev already has a slave with the same #NMDevice:physical-port-id + * Checks if @self already has a slave with the same #NMDevice:physical-port-id * as @slave, and logs a warning if so. */ void -nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, +nm_device_master_check_slave_physical_port (NMDevice *self, NMDevice *slave, guint64 log_domain) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *slave_physical_port_id, *existing_physical_port_id; SlaveInfo *info; GSList *iter; @@ -1322,10 +1541,9 @@ nm_device_master_check_slave_physical_port (NMDevice *dev, NMDevice *slave, existing_physical_port_id = nm_device_get_physical_port_id (info->slave); if (!g_strcmp0 (slave_physical_port_id, existing_physical_port_id)) { - nm_log_warn (log_domain, "(%s): slave %s shares a physical port with existing slave %s", - nm_device_get_ip_iface (dev), - nm_device_get_ip_iface (slave), - nm_device_get_ip_iface (info->slave)); + _LOGW (log_domain, "slave %s shares a physical port with existing slave %s", + nm_device_get_ip_iface (slave), + nm_device_get_ip_iface (info->slave)); /* Since this function will get called for every slave, we only have * to warn about the first match we find; if there are other matches * later in the list, we will have already warned about them matching @@ -1344,7 +1562,7 @@ nm_device_master_release_slaves (NMDevice *self) NMDeviceStateReason reason; /* Don't release the slaves if this connection doesn't belong to NM. */ - if (nm_device_uses_generated_connection (self)) + if (nm_device_uses_generated_assumed_connection (self)) return; reason = priv->state_reason; @@ -1360,19 +1578,19 @@ nm_device_master_release_slaves (NMDevice *self) /** * nm_device_get_master: - * @dev: the device + * @self: the device * - * If @dev has been enslaved by another device, this returns that + * If @self has been enslaved by another device, this returns that * device. Otherwise it returns %NULL. (In particular, note that if - * @dev is in the process of activating as a slave, but has not yet + * @self is in the process of activating as a slave, but has not yet * been enslaved by its master, this will return %NULL.) * - * Returns: (transfer none): @dev's master, or %NULL + * Returns: (transfer none): @self's master, or %NULL */ NMDevice * -nm_device_get_master (NMDevice *dev) +nm_device_get_master (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->enslaved) return priv->master; @@ -1382,17 +1600,17 @@ nm_device_get_master (NMDevice *dev) /** * nm_device_slave_notify_enslave: - * @dev: the slave device + * @self: the slave device * @success: whether the enslaving operation succeeded * * Notifies a slave that either it has been enslaved, or else its master tried * to enslave it and failed. */ static void -nm_device_slave_notify_enslave (NMDevice *dev, gboolean success) +nm_device_slave_notify_enslave (NMDevice *self, gboolean success) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - NMConnection *connection = nm_device_get_connection (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection = nm_device_get_connection (self); gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); g_assert (priv->master); @@ -1400,49 +1618,41 @@ nm_device_slave_notify_enslave (NMDevice *dev, gboolean success) if (!priv->enslaved) { if (success) { if (activating) { - nm_log_info (LOGD_DEVICE, - "Activation (%s) connection '%s' enslaved, continuing activation", - nm_device_get_iface (dev), - nm_connection_get_id (connection)); - } else { - nm_log_info (LOGD_DEVICE, - "(%s): enslaved to %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->master)); - } + _LOGI (LOGD_DEVICE, "Activation: connection '%s' enslaved, continuing activation", + nm_connection_get_id (connection)); + } else + _LOGI (LOGD_DEVICE, "enslaved to %s", nm_device_get_iface (priv->master)); priv->enslaved = TRUE; - g_object_notify (G_OBJECT (dev), NM_DEVICE_MASTER); + g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER); } else if (activating) { - nm_log_warn (LOGD_DEVICE, - "Activation (%s) connection '%s' could not be enslaved", - nm_device_get_iface (dev), - nm_connection_get_id (connection)); + _LOGW (LOGD_DEVICE, "Activation: connection '%s' could not be enslaved", + nm_connection_get_id (connection)); } } if (activating) { priv->ip4_state = IP_DONE; priv->ip6_state = IP_DONE; - nm_device_queue_state (dev, + nm_device_queue_state (self, success ? NM_DEVICE_STATE_SECONDARIES : NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE); } else - nm_device_queue_recheck_assume (dev); + nm_device_queue_recheck_assume (self); } /** * nm_device_slave_notify_release: - * @dev: the slave device + * @self: the slave device * @reason: the reason associated with the state change * * Notifies a slave that it has been released, and why. */ static void -nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason) +nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - NMConnection *connection = nm_device_get_connection (dev); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection = nm_device_get_connection (self); NMDeviceState new_state; const char *master_status; @@ -1460,43 +1670,56 @@ nm_device_slave_notify_release (NMDevice *dev, NMDeviceStateReason reason) master_status = "deactivated"; } - nm_log_dbg (LOGD_DEVICE, - "Activation (%s) connection '%s' master %s", - nm_device_get_iface (dev), - nm_connection_get_id (connection), - master_status); + _LOGD (LOGD_DEVICE, "Activation: connection '%s' master %s", + nm_connection_get_id (connection), + master_status); - nm_device_queue_state (dev, new_state, reason); - } else { - nm_log_info (LOGD_DEVICE, - "(%s): released from master %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->master)); - } + nm_device_queue_state (self, new_state, reason); + } else if (priv->master) + _LOGI (LOGD_DEVICE, "released from master %s", nm_device_get_iface (priv->master)); + else + _LOGD (LOGD_DEVICE, "released from master%s", priv->enslaved ? "" : " (was not enslaved)"); if (priv->enslaved) { priv->enslaved = FALSE; - g_object_notify (G_OBJECT (dev), NM_DEVICE_MASTER); + g_object_notify (G_OBJECT (self), NM_DEVICE_MASTER); } } /** * nm_device_get_enslaved: - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is enslaved to a master device (eg bridge or * bond or team), %FALSE if not */ gboolean -nm_device_get_enslaved (NMDevice *device) +nm_device_get_enslaved (NMDevice *self) +{ + return NM_DEVICE_GET_PRIVATE (self)->enslaved; +} + +/** + * nm_device_removed: + * @self: the #NMDevice + * + * Called by the manager when the device was removed. Releases the device from + * the master in case it's enslaved. + */ +void +nm_device_removed (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->enslaved; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->enslaved) + nm_device_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_REMOVED); } + static gboolean -is_available (NMDevice *device) +is_available (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return priv->carrier || priv->ignore_carrier; } @@ -1548,12 +1771,44 @@ nm_device_set_enabled (NMDevice *self, gboolean enabled) NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled); } +/** + * nm_device_get_autoconnect: + * @self: the #NMDevice + * + * Returns: %TRUE if the device allows autoconnect connections, or %FALSE if the + * device is explicitly blocking all autoconnect connections. Does not take + * into account transient conditions like companion devices that may wish to + * block the device. + */ gboolean -nm_device_get_autoconnect (NMDevice *device) +nm_device_get_autoconnect (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + return NM_DEVICE_GET_PRIVATE (self)->autoconnect; +} + +static void +nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->autoconnect == autoconnect) + return; - return NM_DEVICE_GET_PRIVATE (device)->autoconnect; + if (autoconnect) { + /* Default-unmanaged devices never autoconnect */ + if (!nm_device_get_default_unmanaged (self)) { + priv->autoconnect = TRUE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } + } else { + priv->autoconnect = FALSE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } } static gboolean @@ -1566,6 +1821,14 @@ autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, return TRUE; } +/** + * nm_device_autoconnect_allowed: + * @self: the #NMDevice + * + * Returns: %TRUE if the device can be auto-connected immediately, taking + * transient conditions into account (like companion devices that may wish to + * block autoconnect for a time). + */ gboolean nm_device_autoconnect_allowed (NMDevice *self) { @@ -1573,6 +1836,16 @@ nm_device_autoconnect_allowed (NMDevice *self) GValue instance = G_VALUE_INIT; GValue retval = G_VALUE_INIT; + if (priv->state < NM_DEVICE_STATE_DISCONNECTED || !priv->autoconnect) + return FALSE; + + /* The 'autoconnect-allowed' signal is emitted on a device to allow + * other listeners to block autoconnect on the device if they wish. + * This is mainly used by the OLPC Mesh devices to block autoconnect + * on their companion WiFi device as they share radio resources and + * cannot be connected at the same time. + */ + g_value_init (&instance, G_TYPE_OBJECT); g_value_set_object (&instance, self); @@ -1590,7 +1863,7 @@ nm_device_autoconnect_allowed (NMDevice *self) } static gboolean -can_auto_connect (NMDevice *device, +can_auto_connect (NMDevice *self, NMConnection *connection, char **specific_object) { @@ -1600,13 +1873,44 @@ can_auto_connect (NMDevice *device, if (!nm_setting_connection_get_autoconnect (s_con)) return FALSE; - return nm_device_connection_is_available (device, connection, FALSE); + return nm_device_connection_is_available (self, connection, FALSE); +} + +/** + * nm_device_can_auto_connect: + * @self: an #NMDevice + * @connection: a #NMConnection + * @specific_object: (out) (transfer full): on output, the path of an + * object associated with the returned connection, to be passed to + * nm_manager_activate_connection(), or %NULL. + * + * Checks if @connection can be auto-activated on @self right now. + * This requires, at a minimum, that the connection be compatible with + * @self, and that it have the #NMSettingConnection:autoconnect property + * set, and that the device allow auto connections. Some devices impose + * additional requirements. (Eg, a Wi-Fi connection can only be activated + * if its SSID was seen in the last scan.) + * + * Returns: %TRUE, if the @connection can be auto-activated. + **/ +gboolean +nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (specific_object && !*specific_object, FALSE); + + if (nm_device_autoconnect_allowed (self)) + return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object); + return FALSE; } static gboolean -device_has_config (NMDevice *device) +device_has_config (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); /* Check for IP configuration. */ if (priv->ip4_config && nm_ip4_config_get_num_addresses (priv->ip4_config)) @@ -1615,7 +1919,7 @@ device_has_config (NMDevice *device) return TRUE; /* The existence of a software device is good enough. */ - if (nm_device_is_software (device)) + if (nm_device_is_software (self)) return TRUE; /* Slaves are also configured by definition */ @@ -1625,20 +1929,64 @@ device_has_config (NMDevice *device) return FALSE; } +/** + * nm_device_master_update_slave_connection: + * @self: the master #NMDevice + * @slave: the slave #NMDevice + * @connection: the #NMConnection to update with the slave settings + * @GError: (out): error description + * + * Reads the slave configuration for @slave and updates @connection with those + * properties. This invokes a virtual function on the master device @self. + * + * Returns: %TRUE if the configuration was read and @connection updated, + * %FALSE on failure. + */ +gboolean +nm_device_master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + NMDeviceClass *klass; + gboolean success; + + g_return_val_if_fail (self, FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (slave, FALSE); + g_return_val_if_fail (connection, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + g_return_val_if_fail (nm_connection_get_setting_connection (connection), FALSE); + + g_return_val_if_fail (nm_device_get_iface (self), FALSE); + + klass = NM_DEVICE_GET_CLASS (self); + if (klass->master_update_slave_connection) { + success = klass->master_update_slave_connection (self, slave, connection, error); + + g_return_val_if_fail (!error || (success && !*error) || *error, success); + return success; + } + + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "master device '%s' cannot update a slave connection for slave device '%s' (master type not supported?)", + nm_device_get_iface (self), nm_device_get_iface (slave)); + return FALSE; +} + NMConnection * -nm_device_generate_connection (NMDevice *device) +nm_device_generate_connection (NMDevice *self, NMDevice *master) { - NMDeviceClass *klass = NM_DEVICE_GET_CLASS (device); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *ifname = nm_device_get_iface (device); - int ifindex = nm_device_get_ifindex (device); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + const char *ifname = nm_device_get_iface (self); NMConnection *connection; NMSetting *s_con; NMSetting *s_ip4; NMSetting *s_ip6; gs_free char *uuid = NULL; - gs_free char *name = NULL; - int master_ifindex = 0; const char *ip4_method, *ip6_method; GError *error = NULL; @@ -1647,32 +1995,18 @@ nm_device_generate_connection (NMDevice *device) return NULL; /* Return NULL if device is unconfigured. */ - if (!device_has_config (device)) { - nm_log_dbg (LOGD_DEVICE, "(%s): device has no existing configuration", ifname); + if (!device_has_config (self)) { + _LOGD (LOGD_DEVICE, "device has no existing configuration"); return NULL; } - if (ifindex) - master_ifindex = nm_platform_link_get_master (ifindex); - if (master_ifindex) { - NMDevice *master; - - master = nm_manager_get_device_by_ifindex (nm_manager_get (), master_ifindex); - if (!master || !nm_device_get_act_request (master)) { - nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s)", - ifname, nm_platform_link_get_name (master_ifindex)); - return NULL; - } - } - - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_con = nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); - name = g_strdup_printf ("%s", ifname); g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_ID, name, + NM_SETTING_CONNECTION_ID, ifname, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), @@ -1682,36 +2016,18 @@ nm_device_generate_connection (NMDevice *device) nm_connection_add_setting (connection, s_con); /* If the device is a slave, update various slave settings */ - if (master_ifindex) { - const char *master_iface = nm_platform_link_get_name (master_ifindex); - const char *slave_type = NULL; - gboolean success = FALSE; - - switch (nm_platform_link_get_type (master_ifindex)) { - case NM_LINK_TYPE_BRIDGE: - slave_type = NM_SETTING_BRIDGE_SETTING_NAME; - success = nm_bridge_update_slave_connection (device, connection); - break; - case NM_LINK_TYPE_BOND: - slave_type = NM_SETTING_BOND_SETTING_NAME; - success = TRUE; - break; - case NM_LINK_TYPE_TEAM: - slave_type = NM_SETTING_TEAM_SETTING_NAME; - success = nm_team_update_slave_connection (device, connection); - break; - default: - g_warn_if_reached (); - break; + if (master) { + if (!nm_device_master_update_slave_connection (master, + self, + connection, + &error)) + { + _LOGE (LOGD_DEVICE, "master device '%s' failed to update slave connection: %s", + nm_device_get_iface (master), error ? error->message : "(unknown error)"); + g_error_free (error); + g_object_unref (connection); + return NULL; } - - if (!success) - nm_log_err (LOGD_DEVICE, "(%s): failed to read slave configuration", ifname); - - g_object_set (s_con, - NM_SETTING_CONNECTION_MASTER, master_iface, - NM_SETTING_CONNECTION_SLAVE_TYPE, slave_type, - NULL); } else { /* Only regular and master devices get IP configuration; slaves do not */ s_ip4 = nm_ip4_config_create_setting (priv->ip4_config); @@ -1721,12 +2037,11 @@ nm_device_generate_connection (NMDevice *device) nm_connection_add_setting (connection, s_ip6); } - klass->update_connection (device, connection); + klass->update_connection (self, connection); /* Check the connection in case of update_connection() bug. */ if (!nm_connection_verify (connection, &error)) { - nm_log_err (LOGD_DEVICE, "(%s): Generated connection does not verify: %s", - nm_device_get_iface (device), error->message); + _LOGE (LOGD_DEVICE, "Generated connection does not verify: %s", error->message); g_clear_error (&error); g_object_unref (connection); return NULL; @@ -1739,8 +2054,9 @@ nm_device_generate_connection (NMDevice *device) ip6_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); if ( g_strcmp0 (ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0 && g_strcmp0 (ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0 - && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con))) { - nm_log_dbg (LOGD_DEVICE, "(%s): ignoring generated connection (no IP and not slave)", ifname); + && !nm_setting_connection_get_master (NM_SETTING_CONNECTION (s_con)) + && !priv->slaves) { + _LOGD (LOGD_DEVICE, "ignoring generated connection (no IP and not in master-slave relationship)"); g_object_unref (connection); connection = NULL; } @@ -1748,46 +2064,6 @@ nm_device_generate_connection (NMDevice *device) return connection; } -/** - * nm_device_get_best_auto_connection: - * @dev: an #NMDevice - * @connections: (element-type #NMConnection): a list of connections - * @specific_object: (out) (transfer full): on output, the path of an - * object associated with the returned connection, to be passed to - * nm_manager_activate_connection(), or %NULL. - * - * Looks through @connections to see if there is a connection that can - * be auto-activated on @dev right now. This requires, at a minimum, - * that the connection be compatible with @dev, and that it have the - * #NMSettingConnection:autoconnect property set. Some devices impose - * additional requirements. (Eg, a Wi-Fi connection can only be - * activated if its SSID was seen in the last scan.) - * - * Returns: an auto-activatable #NMConnection, or %NULL if none are - * available. - */ - -NMConnection * -nm_device_get_best_auto_connection (NMDevice *dev, - GSList *connections, - char **specific_object) -{ - GSList *iter; - - g_return_val_if_fail (NM_IS_DEVICE (dev), NULL); - g_return_val_if_fail (specific_object != NULL, NULL); - g_return_val_if_fail (*specific_object == NULL, NULL); - - for (iter = connections; iter; iter = iter->next) { - NMConnection *connection = NM_CONNECTION (iter->data); - - if (NM_DEVICE_GET_CLASS (dev)->can_auto_connect (dev, connection, specific_object)) - return connection; - } - - return NULL; -} - gboolean nm_device_complete_connection (NMDevice *self, NMConnection *connection, @@ -1801,7 +2077,7 @@ nm_device_complete_connection (NMDevice *self, g_return_val_if_fail (connection != NULL, FALSE); if (!NM_DEVICE_GET_CLASS (self)->complete_connection) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CONNECTION_INVALID, + g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "Device class %s had no complete_connection method", G_OBJECT_TYPE_NAME (self)); return FALSE; @@ -1819,7 +2095,7 @@ nm_device_complete_connection (NMDevice *self, } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection) +check_connection_compatible (NMDevice *self, NMConnection *connection) { NMSettingConnection *s_con; const char *config_iface, *device_iface; @@ -1828,7 +2104,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) g_assert (s_con); config_iface = nm_setting_connection_get_interface_name (s_con); - device_iface = nm_device_get_iface (device); + device_iface = nm_device_get_iface (self); if (config_iface && strcmp (config_iface, device_iface) != 0) return FALSE; @@ -1837,43 +2113,31 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) /** * nm_device_check_connection_compatible: - * @device: an #NMDevice + * @self: an #NMDevice * @connection: an #NMConnection * - * Checks if @connection could potentially be activated on @device. - * This means only that @device has the proper capabilities, and that + * Checks if @connection could potentially be activated on @self. + * This means only that @self has the proper capabilities, and that * @connection is not locked to some other device. It does not - * necessarily mean that @connection could be activated on @device + * necessarily mean that @connection could be activated on @self * right now. (Eg, it might refer to a Wi-Fi network that is not * currently available.) * * Returns: #TRUE if @connection could potentially be activated on - * @device. + * @self. */ gboolean -nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection) +nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - return NM_DEVICE_GET_CLASS (device)->check_connection_compatible (device, connection); -} - -static gboolean -string_in_list (const char *str, const char **array, gsize array_len) -{ - gsize i; - - for (i = 0; i < array_len; i++) { - if (strcmp (str, array[i]) == 0) - return TRUE; - } - return FALSE; + return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection); } /** * nm_device_can_assume_connections: - * @device: #NMDevice instance + * @self: #NMDevice instance * * This is a convenience function to determine whether connection assumption * is available for this device. @@ -1881,14 +2145,14 @@ string_in_list (const char *str, const char **array, gsize array_len) * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not */ static gboolean -nm_device_can_assume_connections (NMDevice *device) +nm_device_can_assume_connections (NMDevice *self) { - return !!NM_DEVICE_GET_CLASS (device)->update_connection; + return !!NM_DEVICE_GET_CLASS (self)->update_connection; } /** * nm_device_can_assume_active_connection: - * @device: #NMDevice instance + * @self: #NMDevice instance * * This is a convenience function to determine whether the device's active * connection can be assumed if NetworkManager restarts. This method returns @@ -1900,9 +2164,9 @@ nm_device_can_assume_connections (NMDevice *device) * assumed. */ gboolean -nm_device_can_assume_active_connection (NMDevice *device) +nm_device_can_assume_active_connection (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; const char *method; const char *assumable_ip6_methods[] = { @@ -1911,17 +2175,19 @@ nm_device_can_assume_active_connection (NMDevice *device) NM_SETTING_IP6_CONFIG_METHOD_DHCP, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL }; const char *assumable_ip4_methods[] = { NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NULL }; - if (!nm_device_can_assume_connections (device)) + if (!nm_device_can_assume_connections (self)) return FALSE; - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); if (!connection) return FALSE; @@ -1934,11 +2200,11 @@ nm_device_can_assume_active_connection (NMDevice *device) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (!string_in_list (method, assumable_ip6_methods, G_N_ELEMENTS (assumable_ip6_methods))) + if (!_nm_utils_string_in_list (method, assumable_ip6_methods)) return FALSE; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!string_in_list (method, assumable_ip4_methods, G_N_ELEMENTS (assumable_ip4_methods))) + if (!_nm_utils_string_in_list (method, assumable_ip4_methods)) return FALSE; return TRUE; @@ -1950,8 +2216,10 @@ nm_device_emit_recheck_assume (gpointer self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); priv->recheck_assume_id = 0; - if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config)) + if (!nm_device_get_act_request (self)) { + _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal"); g_signal_emit (self, signals[RECHECK_ASSUME], 0); + } return G_SOURCE_REMOVE; } @@ -2022,9 +2290,8 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) act_source_func = &priv->act_source_func; } - if (*act_source_id) { - nm_log_err (LOGD_DEVICE, "activation stage already scheduled"); - } + if (*act_source_id) + _LOGE (LOGD_DEVICE, "activation stage already scheduled"); /* Don't bother rescheduling the same function that's about to * run anyway. Fixes issues with crappy wireless drivers sending @@ -2038,12 +2305,11 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family) } } -gboolean -nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) +static gboolean +get_ip_config_may_fail (NMDevice *self, int family) { NMConnection *connection; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip = NULL; g_return_val_if_fail (self != NULL, TRUE); @@ -2051,17 +2317,18 @@ nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6) g_assert (connection); /* Fail the connection if the failed IP method is required to complete */ - if (ip6) { - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!nm_setting_ip6_config_get_may_fail (s_ip6)) - return TRUE; - } else { - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (!nm_setting_ip4_config_get_may_fail (s_ip4)) - return TRUE; + switch (family) { + case AF_INET: + s_ip = nm_connection_get_setting_ip4_config (connection); + break; + case AF_INET6: + s_ip = nm_connection_get_setting_ip6_config (connection); + break; + default: + g_assert_not_reached (); } - return FALSE; + return nm_setting_ip_config_get_may_fail (s_ip); } static void @@ -2083,9 +2350,8 @@ master_ready_cb (NMActiveConnection *active, self, nm_active_connection_get_assumed (active) ? FALSE : TRUE); - nm_log_dbg (LOGD_DEVICE, "(%s): master connection ready; master device %s", - nm_device_get_iface (self), - nm_device_get_iface (priv->master)); + _LOGD (LOGD_DEVICE, "master connection ready; master device %s", + nm_device_get_iface (priv->master)); if (priv->master_ready_id) { g_signal_handler_disconnect (active, priv->master_ready_id); @@ -2112,7 +2378,6 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; NMActiveConnection *active = NM_ACTIVE_CONNECTION (priv->act_request); @@ -2125,8 +2390,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) /* Notify the new ActiveConnection along with the state change */ g_object_notify (G_OBJECT (self), NM_DEVICE_ACTIVE_CONNECTION); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) started..."); nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE); /* Assumed connections were already set up outside NetworkManager */ @@ -2146,8 +2410,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) if (nm_active_connection_get_master_ready (active)) master_ready_cb (active, NULL, self); else { - nm_log_dbg (LOGD_DEVICE, "(%s): waiting for master connection to become ready", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "waiting for master connection to become ready"); /* Attach a signal handler and wait for the master connection to begin activating */ g_assert (priv->master_ready_id == 0); @@ -2161,7 +2424,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) nm_device_activate_schedule_stage2_device_config (self); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) complete."); return FALSE; } @@ -2184,12 +2447,11 @@ nm_device_activate_schedule_stage1_device_prepare (NMDevice *self) activation_source_schedule (self, nm_device_activate_stage1_device_prepare, 0); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 1 of 5 (Device Prepare) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 1 of 5 (Device Prepare) scheduled..."); } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *self, NMDeviceStateReason *reason) { /* Nothing to do */ return NM_ACT_STAGE_RETURN_SUCCESS; @@ -2207,7 +2469,6 @@ nm_device_activate_stage2_device_config (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; gboolean no_firmware = FALSE; @@ -2217,8 +2478,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, 0); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) starting..."); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); /* Assumed connections were already set up outside NetworkManager */ @@ -2248,17 +2508,17 @@ nm_device_activate_stage2_device_config (gpointer user_data) if (slave_state == NM_DEVICE_STATE_IP_CONFIG) nm_device_enslave_slave (self, info->slave, nm_device_get_connection (info->slave)); - else if ( nm_device_uses_generated_connection (self) + else if ( nm_device_uses_generated_assumed_connection (self) && slave_state <= NM_DEVICE_STATE_DISCONNECTED) nm_device_queue_recheck_assume (info->slave); } - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) successful.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) successful."); nm_device_activate_schedule_stage3_ip_config_start (self); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) complete."); return FALSE; } @@ -2281,8 +2541,7 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self) activation_source_schedule (self, nm_device_activate_stage2_device_config, 0); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 2 of 5 (Device Configure) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 2 of 5 (Device Configure) scheduled..."); } /*********************************************/ @@ -2310,13 +2569,7 @@ aipd_cleanup (NMDevice *self) } if (priv->aipd_pid > 0) { - kill (priv->aipd_pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_AUTOIP4, "waiting for avahi-autoipd pid %d to exit", priv->aipd_pid); - waitpid (priv->aipd_pid, NULL, 0); - nm_log_dbg (LOGD_AUTOIP4, "avahi-autoip pid %d cleaned up", priv->aipd_pid); - + nm_utils_kill_child_sync (priv->aipd_pid, SIGKILL, LOGD_AUTOIP4, "avahi-autoipd", NULL, 0, 0); priv->aipd_pid = -1; } @@ -2336,15 +2589,15 @@ aipd_get_ip4_config (NMDevice *self, guint32 lla) memset (&address, 0, sizeof (address)); address.address = lla; address.plen = 16; - address.source = NM_PLATFORM_SOURCE_IP4LL; + address.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_PLATFORM_SOURCE_IP4LL; - route.metric = nm_device_get_priority (self); + route.source = NM_IP_CONFIG_SOURCE_IP4LL; + route.metric = nm_device_get_ip4_route_metric (self); nm_ip4_config_add_route (config, &route); return config; @@ -2360,7 +2613,7 @@ nm_device_handle_autoip4_event (NMDevice *self, { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection = NULL; - const char *iface, *method; + const char *method; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; g_return_if_fail (event != NULL); @@ -2376,29 +2629,25 @@ nm_device_handle_autoip4_event (NMDevice *self, if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) != 0) return; - iface = nm_device_get_iface (self); - if (strcmp (event, "BIND") == 0) { guint32 lla; NMIP4Config *config; if (inet_pton (AF_INET, address, &lla) <= 0) { - nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd.", - iface, address); + _LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd.", address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } if ((lla & IPV4LL_NETMASK) != IPV4LL_NETWORK) { - nm_log_err (LOGD_AUTOIP4, "(%s): invalid address %s received from avahi-autoipd (not link-local).", - iface, address); + _LOGE (LOGD_AUTOIP4, "invalid address %s received from avahi-autoipd (not link-local).", address); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR); return; } config = aipd_get_ip4_config (self, lla); if (config == NULL) { - nm_log_err (LOGD_AUTOIP4, "failed to get autoip config"); + _LOGE (LOGD_AUTOIP4, "failed to get autoip config"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); return; } @@ -2408,8 +2657,7 @@ nm_device_handle_autoip4_event (NMDevice *self, nm_device_activate_schedule_ip4_config_result (self, config); } else if (priv->ip4_state == IP_DONE) { if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) { - nm_log_err (LOGD_AUTOIP4, "(%s): failed to update IP4 config for autoip change.", - nm_device_get_iface (self)); + _LOGE (LOGD_AUTOIP4, "failed to update IP4 config for autoip change."); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } } else @@ -2417,8 +2665,7 @@ nm_device_handle_autoip4_event (NMDevice *self, g_object_unref (config); } else { - nm_log_warn (LOGD_AUTOIP4, "(%s): autoip address %s no longer valid because '%s'.", - iface, address, event); + _LOGW (LOGD_AUTOIP4, "autoip address %s no longer valid because '%s'.", address, event); /* The address is gone; terminate the connection or fail activation */ nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); @@ -2431,26 +2678,19 @@ aipd_watch_cb (GPid pid, gint status, gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; - const char *iface; if (!priv->aipd_watch) return; priv->aipd_watch = 0; - iface = nm_device_get_iface (self); - - if (WIFEXITED (status)) { - nm_log_dbg (LOGD_AUTOIP4, "(%s): avahi-autoipd exited with error code %d", - iface, WEXITSTATUS (status)); - } else if (WIFSTOPPED (status)) { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd stopped unexpectedly with signal %d", - iface, WSTOPSIG (status)); - } else if (WIFSIGNALED (status)) { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd died with signal %d", - iface, WTERMSIG (status)); - } else { - nm_log_warn (LOGD_AUTOIP4, "(%s): avahi-autoipd died from an unknown cause", iface); - } + if (WIFEXITED (status)) + _LOGD (LOGD_AUTOIP4, "avahi-autoipd exited with error code %d", WEXITSTATUS (status)); + else if (WIFSTOPPED (status)) + _LOGW (LOGD_AUTOIP4, "avahi-autoipd stopped unexpectedly with signal %d", WSTOPSIG (status)); + else if (WIFSIGNALED (status)) + _LOGW (LOGD_AUTOIP4, "avahi-autoipd died with signal %d", WTERMSIG (status)); + else + _LOGW (LOGD_AUTOIP4, "avahi-autoipd died from an unknown cause"); aipd_cleanup (self); @@ -2466,7 +2706,7 @@ aipd_timeout_cb (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->aipd_timeout) { - nm_log_info (LOGD_AUTOIP4, "(%s): avahi-autoipd timed out.", nm_device_get_iface (self)); + _LOGI (LOGD_AUTOIP4, "avahi-autoipd timed out."); priv->aipd_timeout = 0; aipd_cleanup (self); @@ -2501,63 +2741,51 @@ static NMActStageReturn aipd_start (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (self); - char *argv[6], *cmdline; - const char **aipd_binary = NULL; - static const char *aipd_paths[] = { - "/usr/sbin/avahi-autoipd", - "/usr/local/sbin/avahi-autoipd", - NULL - }; + const char *argv[6]; + char *cmdline; + const char *aipd_binary; int i = 0; GError *error = NULL; aipd_cleanup (self); /* Find avahi-autoipd */ - aipd_binary = aipd_paths; - while (*aipd_binary != NULL) { - if (g_file_test (*aipd_binary, G_FILE_TEST_EXISTS)) - break; - aipd_binary++; - } - - if (!*aipd_binary) { - nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" - " to start avahi-autoipd: not found", iface); + aipd_binary = nm_utils_find_helper ("avahi-autoipd", NULL, NULL); + if (!aipd_binary) { + _LOGW (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: not found"); *reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } - argv[i++] = (char *) (*aipd_binary); + argv[i++] = aipd_binary; argv[i++] = "--script"; - argv[i++] = (char *) nm_device_autoipd_helper_path; + argv[i++] = nm_device_autoipd_helper_path; if (nm_logging_enabled (LOGL_DEBUG, LOGD_AUTOIP4)) argv[i++] = "--debug"; - argv[i++] = (char *) nm_device_get_ip_iface (self); + argv[i++] = nm_device_get_ip_iface (self); argv[i++] = NULL; - cmdline = g_strjoinv (" ", argv); - nm_log_dbg (LOGD_AUTOIP4, "running: %s", cmdline); + cmdline = g_strjoinv (" ", (char **) argv); + _LOGD (LOGD_AUTOIP4, "running: %s", cmdline); g_free (cmdline); - if (!g_spawn_async ("/", argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, + if (!g_spawn_async ("/", (char **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, &aipd_child_setup, NULL, &(priv->aipd_pid), &error)) { - nm_log_warn (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) failed" - " to start avahi-autoipd: %s", - iface, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) failed" + " to start avahi-autoipd: %s", + error && error->message ? error->message : "(unknown)"); g_clear_error (&error); aipd_cleanup (self); return NM_ACT_STAGE_RETURN_FAILURE; } - nm_log_info (LOGD_DEVICE | LOGD_AUTOIP4, - "Activation (%s) Stage 3 of 5 (IP Configure Start) started" - " avahi-autoipd...", iface); + _LOGI (LOGD_DEVICE | LOGD_AUTOIP4, + "Activation: Stage 3 of 5 (IP Configure Start) started" + " avahi-autoipd..."); /* Monitor the child process so we know when it dies */ priv->aipd_watch = g_child_watch_add (priv->aipd_pid, aipd_watch_cb, self); @@ -2568,6 +2796,52 @@ aipd_start (NMDevice *self, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_POSTPONE; } +/*********************************************/ + +static gboolean +_device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlatformIPRoute *out_route) +{ + gboolean success = FALSE; + int ifindex = nm_device_get_ip_ifindex (self); + GArray *routes; + + if (addr_family == AF_INET) + routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + else + routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + + if (routes) { + guint route_metric = G_MAXUINT32, m; + const NMPlatformIPRoute *route = NULL, *r; + guint i; + + /* if there are several default routes, find the one with the best metric */ + for (i = 0; i < routes->len; i++) { + if (addr_family == AF_INET) { + r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, i); + m = r->metric; + } else { + r = (const NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, i); + m = nm_utils_ip6_route_metric_normalize (r->metric); + } + if (!route || m < route_metric) { + route = r; + route_metric = m; + } + } + + if (route) { + if (addr_family == AF_INET) + *((NMPlatformIP4Route *) out_route) = *((NMPlatformIP4Route *) route); + else + *((NMPlatformIP6Route *) out_route) = *((NMPlatformIP6Route *) route); + success = TRUE; + } + g_array_free (routes, TRUE); + } + return success; +} + /*********************************************/ /* DHCPv4 stuff */ @@ -2583,11 +2857,6 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) priv->dhcp4_state_sigid = 0; } - if (priv->dhcp4_timeout_sigid) { - g_signal_handler_disconnect (priv->dhcp4_client, priv->dhcp4_timeout_sigid); - priv->dhcp4_timeout_sigid = 0; - } - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP4, FALSE); if (stop) @@ -2602,14 +2871,6 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) } } -static void -dhcp4_add_option_cb (gpointer key, gpointer value, gpointer user_data) -{ - nm_dhcp4_config_add_option (NM_DHCP4_CONFIG (user_data), - (const char *) key, - (const char *) value); -} - static gboolean ip4_config_merge_and_apply (NMDevice *self, NMIP4Config *config, @@ -2620,6 +2881,7 @@ ip4_config_merge_and_apply (NMDevice *self, NMConnection *connection; gboolean success; NMIP4Config *composite; + const guint32 default_route_metric = nm_device_get_ip4_route_metric (self); /* Merge all the configs into the composite config */ if (config) { @@ -2635,12 +2897,79 @@ ip4_config_merge_and_apply (NMDevice *self, if (priv->ext_ip4_config) nm_ip4_config_merge (composite, priv->ext_ip4_config); - /* Merge user overrides into the composite config */ + /* Merge WWAN config *last* to ensure modem-given settings overwrite + * any external stuff set by pppd or other scripts. + */ + if (priv->wwan_ip4_config) + nm_ip4_config_merge (composite, priv->wwan_ip4_config); + + /* Merge user overrides into the composite config. Generated+assumed + * connections come from the system not the user and merging them would + * be redundant, so don't bother. + */ connection = nm_device_get_connection (self); + priv->default_route.v4_has = FALSE; + priv->default_route.v4_is_assumed = TRUE; if (connection) { - nm_ip4_config_merge_setting (composite, - nm_connection_get_setting_ip4_config (connection), - nm_device_get_priority (self)); + gboolean assumed = nm_device_uses_assumed_connection (self); + NMPlatformIP4Route *route = &priv->default_route.v4; + + if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) { + nm_ip4_config_merge_setting (composite, + nm_connection_get_setting_ip4_config (connection), + default_route_metric); + } + + /* Add the default route. + * + * We keep track of the default route of a device in a private field. + * NMDevice needs to know the default route at this point, because the gateway + * might require a direct route (see below). + * + * But also, we don't want to add the default route to priv->ip4_config, + * because the default route from the setting might not be the same that + * NMDefaultRouteManager eventually configures (because the it might + * tweak the effective metric). + */ + if ( !assumed + && nm_default_route_manager_ip4_connection_has_default_route (nm_default_route_manager_get (), connection)) { + guint32 gateway = 0; + + priv->default_route.v4_is_assumed = FALSE; + if ( (!commit && priv->ext_ip4_config_had_any_addresses) + || ( commit && nm_ip4_config_get_num_addresses (composite))) { + /* For managed interfaces, we can only configure a gateway, if either the external config indicates + * that we already have addresses, or if we are about to commit any addresses. + * Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any + * addresses for the route. */ + gateway = nm_ip4_config_get_gateway (composite); + if ( gateway + || nm_device_get_device_type (self) == NM_DEVICE_TYPE_MODEM) { + memset (route, 0, sizeof (*route)); + route->source = NM_IP_CONFIG_SOURCE_USER; + route->gateway = gateway; + route->metric = default_route_metric; + route->mss = nm_ip4_config_get_mss (composite); + priv->default_route.v4_has = TRUE; + + if ( gateway + && !nm_ip4_config_get_subnet_for_host (composite, gateway) + && !nm_ip4_config_get_direct_route_for_host (composite, gateway)) { + /* add a direct route to the gateway */ + NMPlatformIP4Route r = *route; + + r.network = gateway; + r.plen = 32; + r.gateway = 0; + nm_ip4_config_add_route (composite, &r); + } + } + } + } else { + /* For interfaces that are assumed and that have no default-route by configuration, we assume + * the default connection and pick up whatever is configured. */ + priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) route); + } } /* Allow setting MTU etc */ @@ -2649,7 +2978,7 @@ ip4_config_merge_and_apply (NMDevice *self, NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, composite); } - success = nm_device_set_ip4_config (self, composite, commit, out_reason); + success = nm_device_set_ip4_config (self, composite, default_route_metric, commit, out_reason); g_object_unref (composite); return success; } @@ -2662,8 +2991,7 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) g_return_if_fail (config != NULL); if (!ip4_config_merge_and_apply (self, config, TRUE, &reason)) { - nm_log_warn (LOGD_DHCP4, "(%s): failed to update IPv4 config for DHCP change.", - nm_device_get_ip_iface (self)); + _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 */ @@ -2677,94 +3005,93 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) } static void -dhcp4_fail (NMDevice *device, gboolean timeout) +dhcp4_fail (NMDevice *self, gboolean timeout) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - nm_dhcp4_config_reset (priv->dhcp4_config); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + dhcp4_cleanup (self, TRUE, FALSE); if (timeout || (priv->ip4_state == IP_CONF)) - nm_device_activate_schedule_ip4_config_timeout (device); - else if (priv->ip4_state == IP_FAIL) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + 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 + g_warn_if_reached (); } static void -dhcp4_state_changed (NMDHCPClient *client, - NMDHCPState state, +dhcp4_update_config (NMDevice *self, NMDhcp4Config *config, GHashTable *options) +{ + GHashTableIter iter; + const char *key, *value; + + /* Update the DHCP4 config object with new DHCP options */ + nm_dhcp4_config_reset (config); + + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) + nm_dhcp4_config_add_option (config, key, value); + + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG); +} + +static void +dhcp4_state_changed (NMDhcpClient *client, + NMDhcpState state, + NMIP4Config *ip4_config, + GHashTable *options, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMIP4Config *config; + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); + g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config)); - nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", - nm_device_get_iface (device), state); + _LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state); switch (state) { - case DHC_BOUND4: /* lease obtained */ - case DHC_RENEW4: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND4: /* new, different lease */ - config = nm_dhcp_client_get_ip4_config (priv->dhcp4_client, FALSE); - if (!config) { - nm_log_warn (LOGD_DHCP4, "(%s): failed to get IPv4 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, + 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); break; } - /* Update the DHCP4 config object with new DHCP options */ - nm_dhcp4_config_reset (priv->dhcp4_config); - nm_dhcp_client_foreach_option (priv->dhcp4_client, - dhcp4_add_option_cb, - priv->dhcp4_config); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP4_CONFIG); + dhcp4_update_config (self, priv->dhcp4_config, options); if (priv->ip4_state == IP_CONF) - nm_device_activate_schedule_ip4_config_result (device, config); + nm_device_activate_schedule_ip4_config_result (self, ip4_config); else if (priv->ip4_state == IP_DONE) - dhcp4_lease_change (device, config); - g_object_unref (config); - + dhcp4_lease_change (self, ip4_config); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ - dhcp4_fail (device, TRUE); + case NM_DHCP_STATE_TIMEOUT: + dhcp4_fail (self, TRUE); break; - case DHC_END: /* dhclient exited normally */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ - /* dhclient quit and can't get/renew a lease; so kill the connection */ - dhcp4_fail (device, FALSE); + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip4_state == IP_CONF) + break; + /* Fall through */ + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: + dhcp4_fail (self, FALSE); break; default: break; } } -static void -dhcp4_timeout (NMDHCPClient *client, gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - - g_return_if_fail (nm_device_get_act_request (device) != NULL); - g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == FALSE); - - nm_dhcp_client_stop (client, FALSE); - dhcp4_fail (device, TRUE); -} - static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; + const guint8 *hw_addr; + size_t hw_addr_len = 0; GByteArray *tmp = NULL; s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -2774,21 +3101,26 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); - if (priv->hw_addr_len) { - tmp = g_byte_array_sized_new (priv->hw_addr_len); - g_byte_array_append (tmp, priv->hw_addr, priv->hw_addr_len); + hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len); + if (hw_addr_len) { + tmp = g_byte_array_sized_new (hw_addr_len); + g_byte_array_append (tmp, hw_addr, hw_addr_len); } /* 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 (), nm_device_get_ip_iface (self), + nm_device_get_ip_ifindex (self), tmp, nm_connection_get_uuid (connection), - nm_device_get_priority (self), - s_ip4, + nm_device_get_ip4_route_metric (self), + nm_setting_ip_config_get_dhcp_send_hostname (s_ip4), + nm_setting_ip_config_get_dhcp_hostname (s_ip4), + nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)), priv->dhcp_timeout, - priv->dhcp_anycast_address); + priv->dhcp_anycast_address, + NULL); if (tmp) g_byte_array_free (tmp, TRUE); @@ -2802,10 +3134,6 @@ dhcp4_start (NMDevice *self, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp4_state_changed), self); - priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client, - NM_DHCP_CLIENT_SIGNAL_TIMEOUT, - G_CALLBACK (dhcp4_timeout), - self); nm_device_add_pending_action (self, PENDING_ACTION_DHCP4, TRUE); @@ -2823,8 +3151,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); - nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 lease renewal requested", - nm_device_get_iface (self)); + _LOGI (LOGD_DHCP4, "DHCPv4 lease renewal requested"); /* Terminate old DHCP instance and release the old lease */ dhcp4_cleanup (self, TRUE, release); @@ -2849,20 +3176,20 @@ release_shared_ip (gpointer data) } static gboolean -reserve_shared_ip (NMSettingIP4Config *s_ip4, NMPlatformIP4Address *address) +reserve_shared_ip (NMDevice *self, NMSettingIPConfig *s_ip4, NMPlatformIP4Address *address) { if (G_UNLIKELY (shared_ips == NULL)) shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal); memset (address, 0, sizeof (*address)); - if (s_ip4 && nm_setting_ip4_config_get_num_addresses (s_ip4)) { + if (s_ip4 && nm_setting_ip_config_get_num_addresses (s_ip4)) { /* Use the first user-supplied address */ - NMIP4Address *user = nm_setting_ip4_config_get_address (s_ip4, 0); + NMIPAddress *user = nm_setting_ip_config_get_address (s_ip4, 0); g_assert (user); - address->address = nm_ip4_address_get_address (user); - address->plen = nm_ip4_address_get_prefix (user); + nm_ip_address_get_address_binary (user, &address->address); + address->plen = nm_ip_address_get_prefix (user); } else { /* Find an unused address in the 10.42.x.x range */ guint32 start = (guint32) ntohl (0x0a2a0001); /* 10.42.0.1 */ @@ -2871,7 +3198,7 @@ reserve_shared_ip (NMSettingIP4Config *s_ip4, NMPlatformIP4Address *address) while (g_hash_table_lookup (shared_ips, GUINT_TO_POINTER (start + count))) { count += ntohl (0x100); if (count > ntohl (0xFE00)) { - nm_log_err (LOGD_SHARING, "ran out of shared IP addresses!"); + _LOGE (LOGD_SHARING, "ran out of shared IP addresses!"); return FALSE; } } @@ -2894,13 +3221,13 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso g_return_val_if_fail (self != NULL, NULL); - if (!reserve_shared_ip (nm_connection_get_setting_ip4_config (connection), &address)) { + if (!reserve_shared_ip (self, nm_connection_get_setting_ip4_config (connection), &address)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NULL; } config = nm_ip4_config_new (); - address.source = NM_PLATFORM_SOURCE_SHARED; + address.source = NM_IP_CONFIG_SOURCE_SHARED; nm_ip4_config_add_address (config, &address); /* Remove the address lock when the object gets disposed */ @@ -2914,7 +3241,79 @@ shared4_new_config (NMDevice *self, NMConnection *connection, NMDeviceStateReaso /*********************************************/ static gboolean -have_any_ready_slaves (NMDevice *device, const GSList *slaves) +connection_ip4_method_requires_carrier (NMConnection *connection, + gboolean *out_ip4_enabled) +{ + const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + static const char *ip4_carrier_methods[] = { + NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NULL + }; + + if (out_ip4_enabled) + *out_ip4_enabled = !!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + return _nm_utils_string_in_list (method, ip4_carrier_methods); +} + +static gboolean +connection_ip6_method_requires_carrier (NMConnection *connection, + gboolean *out_ip6_enabled) +{ + const char *method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + static const char *ip6_carrier_methods[] = { + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NULL + }; + + if (out_ip6_enabled) + *out_ip6_enabled = !!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + return _nm_utils_string_in_list (method, ip6_carrier_methods); +} + +static gboolean +connection_requires_carrier (NMConnection *connection) +{ + NMSettingIPConfig *s_ip4, *s_ip6; + gboolean ip4_carrier_wanted, ip6_carrier_wanted; + gboolean ip4_used = FALSE, ip6_used = FALSE; + + ip4_carrier_wanted = connection_ip4_method_requires_carrier (connection, &ip4_used); + if (ip4_carrier_wanted) { + /* If IPv4 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv6 method. + */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4 && !nm_setting_ip_config_get_may_fail (s_ip4)) + return TRUE; + } + + ip6_carrier_wanted = connection_ip6_method_requires_carrier (connection, &ip6_used); + if (ip6_carrier_wanted) { + /* If IPv6 wants a carrier and cannot fail, the whole connection + * requires a carrier regardless of the IPv4 method. + */ + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6 && !nm_setting_ip_config_get_may_fail (s_ip6)) + return TRUE; + } + + /* If an IP version wants a carrier and and the other IP version isn't + * used, the connection requires carrier since it will just fail without one. + */ + if (ip4_carrier_wanted && !ip6_used) + return TRUE; + if (ip6_carrier_wanted && !ip4_used) + return TRUE; + + /* If both want a carrier, the whole connection wants a carrier */ + return ip4_carrier_wanted && ip6_carrier_wanted; +} + +static gboolean +have_any_ready_slaves (NMDevice *self, const GSList *slaves) { const GSList *iter; @@ -2955,16 +3354,11 @@ act_stage3_ip4_config_start (NMDevice *self, connection = nm_device_get_connection (self); g_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (priv->master) - g_assert_cmpstr (method, ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - - if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0 + if ( connection_ip4_method_requires_carrier (connection, NULL) && priv->is_master && !priv->carrier) { - nm_log_info (LOGD_IP4 | LOGD_DEVICE, - "(%s): IPv4 config waiting until carrier is on", - nm_device_get_ip_iface (self)); + _LOGI (LOGD_IP4 | LOGD_DEVICE, + "IPv4 config waiting until carrier is on"); return NM_ACT_STAGE_RETURN_WAIT; } @@ -2977,13 +3371,14 @@ act_stage3_ip4_config_start (NMDevice *self, g_slist_free (slaves); if (ready_slaves == FALSE) { - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "(%s): IPv4 config waiting until slaves are ready", - nm_device_get_ip_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "IPv4 config waiting until slaves are ready"); return NM_ACT_STAGE_RETURN_WAIT; } } + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + /* Start IPv4 addressing based on the method requested */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) ret = dhcp4_start (self, connection, reason); @@ -3004,10 +3399,8 @@ act_stage3_ip4_config_start (NMDevice *self, } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) { /* Nothing to do... */ ret = NM_ACT_STAGE_RETURN_STOP; - } else { - nm_log_warn (LOGD_IP4, "(%s): unhandled IPv4 config method '%s'; will fail", - nm_device_get_ip_iface (self), method); - } + } else + _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); return ret; } @@ -3029,33 +3422,20 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) priv->dhcp6_state_sigid = 0; } - if (priv->dhcp6_timeout_sigid) { - g_signal_handler_disconnect (priv->dhcp6_client, priv->dhcp6_timeout_sigid); - priv->dhcp6_timeout_sigid = 0; - } - - nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); - if (stop) nm_dhcp_client_stop (priv->dhcp6_client, release); g_clear_object (&priv->dhcp6_client); } + nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); + if (priv->dhcp6_config) { g_clear_object (&priv->dhcp6_config); g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); } } -static void -dhcp6_add_option_cb (gpointer key, gpointer value, gpointer user_data) -{ - nm_dhcp6_config_add_option (NM_DHCP6_CONFIG (user_data), - (const char *) key, - (const char *) value); -} - static gboolean ip6_config_merge_and_apply (NMDevice *self, gboolean commit, @@ -3080,109 +3460,216 @@ ip6_config_merge_and_apply (NMDevice *self, if (priv->ext_ip6_config) nm_ip6_config_merge (composite, priv->ext_ip6_config); - /* Merge user overrides into the composite config */ + /* Merge WWAN config *last* to ensure modem-given settings overwrite + * any external stuff set by pppd or other scripts. + */ + if (priv->wwan_ip6_config) + nm_ip6_config_merge (composite, priv->wwan_ip6_config); + + /* Merge user overrides into the composite config. Generated+assumed + * connections come from the system not the user and merging them would + * be redundant, so don't bother. + */ connection = nm_device_get_connection (self); + priv->default_route.v6_has = FALSE; + priv->default_route.v6_is_assumed = TRUE; if (connection) { - nm_ip6_config_merge_setting (composite, - nm_connection_get_setting_ip6_config (connection), - nm_device_get_priority (self)); + gboolean assumed = nm_device_uses_assumed_connection (self); + NMPlatformIP6Route *route = &priv->default_route.v6; + + if (!nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) { + nm_ip6_config_merge_setting (composite, + nm_connection_get_setting_ip6_config (connection), + nm_device_get_ip6_route_metric (self)); + } + + /* Add the default route. + * + * We keep track of the default route of a device in a private field. + * NMDevice needs to know the default route at this point, because the gateway + * might require a direct route (see below). + * + * But also, we don't want to add the default route to priv->ip4_config, + * because the default route from the setting might not be the same that + * NMDefaultRouteManager eventually configures (because the it might + * tweak the effective metric). + */ + if ( !assumed + && nm_default_route_manager_ip6_connection_has_default_route (nm_default_route_manager_get (), connection)) { + const struct in6_addr *gateway = NULL; + + priv->default_route.v6_is_assumed = FALSE; + if ( (!commit && priv->ext_ip6_config_had_any_addresses) + || ( commit && nm_ip6_config_get_num_addresses (composite))) { + /* For managed interfaces, we can only configure a gateway, if either the external config indicates + * that we already have addresses, or if we are about to commit any addresses. + * Otherwise adding a default route will fail, because NMDefaultRouteManager does not add any + * addresses for the route. */ + gateway = nm_ip6_config_get_gateway (composite); + if (gateway) { + memset (route, 0, sizeof (*route)); + route->source = NM_IP_CONFIG_SOURCE_USER; + route->gateway = *gateway; + route->metric = nm_device_get_ip6_route_metric (self); + route->mss = nm_ip6_config_get_mss (composite); + priv->default_route.v6_has = TRUE; + + if ( gateway + && !nm_ip6_config_get_subnet_for_host (composite, gateway) + && !nm_ip6_config_get_direct_route_for_host (composite, gateway)) { + /* add a direct route to the gateway */ + NMPlatformIP6Route r = *route; + + r.network = *gateway; + r.plen = 128; + r.gateway = in6addr_any; + nm_ip6_config_add_route (composite, &r); + } + } + } + } else { + /* For interfaces that are assumed and that have no default-route by configuration, we assume + * the default connection and pick up whatever is configured. */ + priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) route); + } } nm_ip6_config_addresses_sort (composite, priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + /* Allow setting MTU etc */ + if (commit) { + if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) + NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite); + } + success = nm_device_set_ip6_config (self, composite, commit, out_reason); g_object_unref (composite); return success; } static void -dhcp6_lease_change (NMDevice *device) +dhcp6_lease_change (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; if (priv->dhcp6_ip6_config == NULL) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to get DHCPv6 config for rebind", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + _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; } g_assert (priv->dhcp6_client); /* sanity check */ - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); g_assert (connection); /* Apply the updated config */ - if (ip6_config_merge_and_apply (device, TRUE, &reason) == FALSE) { - nm_log_warn (LOGD_DHCP6, "(%s): failed to update IPv6 config in response to DHCP event.", - nm_device_get_ip_iface (device)); - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + 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, connection, device, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, connection, self, NULL, NULL, NULL); + } +} + +static void +dhcp6_fail (NMDevice *self, gboolean timeout) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + dhcp6_cleanup (self, TRUE, FALSE); + + if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (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 + g_warn_if_reached (); + } else { + /* not a hard failure; just live with the RA info */ + if (priv->ip6_state == IP_CONF) + nm_device_activate_schedule_ip6_config_result (self); + } +} + +static void +dhcp6_timeout (NMDevice *self, NMDhcpClient *client) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) + dhcp6_fail (self, TRUE); + else { + /* not a hard failure; just live with the RA info */ + dhcp6_cleanup (self, TRUE, FALSE); + if (priv->ip6_state == IP_CONF) + nm_device_activate_schedule_ip6_config_result (self); } } static void -dhcp6_fail (NMDevice *device, gboolean timeout) +dhcp6_update_config (NMDevice *self, NMDhcp6Config *config, GHashTable *options) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GHashTableIter iter; + const char *key, *value; - nm_dhcp6_config_reset (priv->dhcp6_config); + /* Update the DHCP6 config object with new DHCP options */ + nm_dhcp6_config_reset (config); - if (timeout || (priv->ip6_state == IP_CONF)) - nm_device_activate_schedule_ip6_config_timeout (device); - else if (priv->ip6_state == IP_FAIL) - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED); + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value)) + nm_dhcp6_config_add_option (config, key, value); + + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); } static void -dhcp6_state_changed (NMDHCPClient *client, - NMDHCPState state, +dhcp6_state_changed (NMDhcpClient *client, + NMDhcpState state, + NMIP6Config *ip6_config, + GHashTable *options, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevice *self = NM_DEVICE (user_data); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); + g_return_if_fail (!ip6_config || NM_IS_IP6_CONFIG (ip6_config)); - nm_log_dbg (LOGD_DHCP6, "(%s): new DHCPv6 client state %d", - nm_device_get_iface (device), state); + _LOGD (LOGD_DHCP6, "new DHCPv6 client state %d", state); switch (state) { - case DHC_BOUND6: - case DHC_RENEW6: /* lease renewed */ - case DHC_REBOOT: /* have valid lease, but now obtained a different one */ - case DHC_REBIND6: /* new, different lease */ + case NM_DHCP_STATE_BOUND: g_clear_object (&priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE); - - /* Update the DHCP6 config object with new DHCP options */ - nm_dhcp6_config_reset (priv->dhcp6_config); - if (priv->dhcp6_ip6_config) { - nm_dhcp_client_foreach_option (priv->dhcp6_client, - dhcp6_add_option_cb, - priv->dhcp6_config); + if (ip6_config) { + priv->dhcp6_ip6_config = g_object_ref (ip6_config); + dhcp6_update_config (self, priv->dhcp6_config, options); } - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG); 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 (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED); break; } - nm_device_activate_schedule_ip6_config_result (device); + nm_device_activate_schedule_ip6_config_result (self); } else if (priv->ip6_state == IP_DONE) - dhcp6_lease_change (device); + dhcp6_lease_change (self); + break; + case NM_DHCP_STATE_TIMEOUT: + dhcp6_timeout (self, client); break; - case DHC_TIMEOUT: /* timed out contacting DHCP server */ - dhcp6_fail (device, TRUE); + case NM_DHCP_STATE_EXPIRE: + /* Ignore expiry before we even have a lease (NAK, old lease, etc) */ + if (priv->ip6_state != IP_CONF) + dhcp6_fail (self, FALSE); break; - case DHC_END: /* dhclient exited normally */ + case NM_DHCP_STATE_DONE: /* In IPv6 info-only mode, the client doesn't handle leases so it * may exit right after getting a response from the server. That's * normal. In that case we just ignore the exit. @@ -3190,83 +3677,45 @@ dhcp6_state_changed (NMDHCPClient *client, if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) break; /* Otherwise, fall through */ - case DHC_FAIL: /* all attempts to contact server timed out, sleeping */ - case DHC_ABEND: /* dhclient exited abnormally */ - /* dhclient quit and can't get/renew a lease; so kill the connection */ - dhcp6_fail (device, FALSE); + case NM_DHCP_STATE_FAIL: + dhcp6_fail (self, FALSE); break; default: break; } } -static void -dhcp6_timeout (NMDHCPClient *client, gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - g_return_if_fail (nm_device_get_act_request (device) != NULL); - g_return_if_fail (nm_dhcp_client_get_ipv6 (client) == TRUE); - - nm_dhcp_client_stop (client, FALSE); - if (priv->dhcp6_mode == NM_RDISC_DHCP_LEVEL_MANAGED) - dhcp6_fail (device, TRUE); - else { - /* not a hard failure; just live with the RA info */ - nm_dhcp6_config_reset (priv->dhcp6_config); - if (priv->dhcp6_ip6_config) - g_object_unref (priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = NULL; - - if (priv->ip6_state == IP_CONF) - nm_device_activate_schedule_ip6_config_result (device); - } -} - -static NMActStageReturn -dhcp6_start (NMDevice *self, - NMConnection *connection, - guint32 dhcp_opt, - NMDeviceStateReason *reason) +static gboolean +dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) { - NMSettingIP6Config *s_ip6; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMSettingIPConfig *s_ip6; GByteArray *tmp = NULL; + const guint8 *hw_addr; + size_t hw_addr_len = 0; - if (!connection) { - connection = nm_device_get_connection (self); - g_assert (connection); - } + g_assert (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); - /* Begin a DHCP transaction on the interface */ - - /* Clear old exported DHCP options */ - if (priv->dhcp6_config) - g_object_unref (priv->dhcp6_config); - priv->dhcp6_config = nm_dhcp6_config_new (); - - g_warn_if_fail (priv->dhcp6_ip6_config == NULL); - if (priv->dhcp6_ip6_config) { - g_object_unref (priv->dhcp6_ip6_config); - priv->dhcp6_ip6_config = NULL; - } - - if (priv->hw_addr_len) { - tmp = g_byte_array_sized_new (priv->hw_addr_len); - g_byte_array_append (tmp, priv->hw_addr, priv->hw_addr_len); - } + hw_addr = nm_platform_link_get_address (nm_device_get_ip_ifindex (self), &hw_addr_len); + if (hw_addr_len) { + tmp = g_byte_array_sized_new (hw_addr_len); + g_byte_array_append (tmp, hw_addr, hw_addr_len); + } 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, nm_connection_get_uuid (connection), - nm_device_get_priority (self), - nm_connection_get_setting_ip6_config (connection), + nm_device_get_ip6_route_metric (self), + nm_setting_ip_config_get_dhcp_send_hostname (s_ip6), + nm_setting_ip_config_get_dhcp_hostname (s_ip6), priv->dhcp_timeout, priv->dhcp_anycast_address, - (dhcp_opt == 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); @@ -3275,65 +3724,85 @@ dhcp6_start (NMDevice *self, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp6_state_changed), self); - priv->dhcp6_timeout_sigid = g_signal_connect (priv->dhcp6_client, - NM_DHCP_CLIENT_SIGNAL_TIMEOUT, - G_CALLBACK (dhcp6_timeout), - self); + } - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (!nm_setting_ip6_config_get_may_fail (s_ip6) || - !strcmp (nm_setting_ip6_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) - nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); + return !!priv->dhcp6_client; +} - /* DHCP devices will be notified by the DHCP manager when stuff happens */ - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else { +static gboolean +dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; + NMSettingIPConfig *s_ip6; + + g_clear_object (&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); + + connection = nm_device_get_connection (self); + g_assert (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (!nm_setting_ip_config_get_may_fail (s_ip6) || + !strcmp (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_DHCP)) + nm_device_add_pending_action (self, PENDING_ACTION_DHCP6, TRUE); + + if (wait_for_ll) { + NMActStageReturn ret; + + /* ensure link local is ready... */ + ret = linklocal6_start (self); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { + /* success; wait for the LL address to show up */ + return TRUE; + } + + /* success; already have the LL address; kick off DHCP */ + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + } + + if (!dhcp6_start_with_link_ready (self, connection)) { *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; - ret = NM_ACT_STAGE_RETURN_FAILURE; + return FALSE; } - return ret; + return TRUE; } gboolean nm_device_dhcp6_renew (NMDevice *self, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret; - NMDeviceStateReason reason; - NMConnection *connection; g_return_val_if_fail (priv->dhcp6_client != NULL, FALSE); - nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 lease renewal requested", - nm_device_get_iface (self)); + _LOGI (LOGD_DHCP6, "DHCPv6 lease renewal requested"); /* Terminate old DHCP instance and release the old lease */ dhcp6_cleanup (self, TRUE, release); - connection = nm_device_get_connection (self); - g_assert (connection); - /* Start DHCP again on the interface */ - ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason); - - return (ret != NM_ACT_STAGE_RETURN_FAILURE); + return dhcp6_start (self, FALSE, NULL); } /******************************************/ static gboolean -linklocal6_config_is_ready (const NMIP6Config *ip6_config) +have_ip6_address (const NMIP6Config *ip6_config, gboolean linklocal) { - int i; + guint i; if (!ip6_config) return FALSE; + linklocal = !!linklocal; + for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) { const NMPlatformIP6Address *addr = nm_ip6_config_get_address (ip6_config, i); - if (IN6_IS_ADDR_LINKLOCAL (&addr->address) && + if ((IN6_IS_ADDR_LINKLOCAL (&addr->address) == linklocal) && !(addr->flags & IFA_F_TENTATIVE)) return TRUE; } @@ -3359,8 +3828,7 @@ linklocal6_timeout_cb (gpointer user_data) linklocal6_cleanup (self); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: waiting for link-local addresses failed due to timeout", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses failed due to timeout"); nm_device_activate_schedule_ip6_config_timeout (self); return G_SOURCE_REMOVE; @@ -3374,7 +3842,7 @@ linklocal6_complete (NMDevice *self) const char *method; g_assert (priv->linklocal6_timeout_id); - g_assert (linklocal6_config_is_ready (priv->ip6_config)); + g_assert (have_ip6_address (priv->ip6_config, TRUE)); linklocal6_cleanup (self); @@ -3383,17 +3851,70 @@ linklocal6_complete (NMDevice *self) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: waiting for link-local addresses successful, continue with method %s", - nm_device_get_iface (self), method); + _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method); - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) - addrconf6_start_with_link_ready (self); - else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { + if (!addrconf6_start_with_link_ready (self)) { + /* Time out IPv6 instead of failing the entire activation */ + nm_device_activate_schedule_ip6_config_timeout (self); + } + } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { + if (!dhcp6_start_with_link_ready (self, connection)) { + /* Time out IPv6 instead of failing the entire activation */ + nm_device_activate_schedule_ip6_config_timeout (self); + } + } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) nm_device_activate_schedule_ip6_config_result (self); else g_return_if_fail (FALSE); } +static void +check_and_add_ipv6ll_addr (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ip_ifindex = nm_device_get_ip_ifindex (self); + NMUtilsIPv6IfaceId iid; + struct in6_addr lladdr; + guint i, n; + + if (priv->nm_ipv6ll == FALSE) + return; + + if (priv->ip6_config) { + n = nm_ip6_config_get_num_addresses (priv->ip6_config); + for (i = 0; i < n; i++) { + const NMPlatformIP6Address *addr; + + addr = nm_ip6_config_get_address (priv->ip6_config, i); + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + /* Already have an LL address, nothing to do */ + return; + } + } + } + + if (!nm_device_get_ip_iface_identifier (self, &iid)) { + _LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 may be broken"); + return; + } + + memset (&lladdr, 0, sizeof (lladdr)); + lladdr.s6_addr16[0] = htons (0xfe80); + nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid); + _LOGD (LOGD_IP6, "adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL)); + if (!nm_platform_ip6_address_add (ip_ifindex, + lladdr, + in6addr_any, + 64, + NM_PLATFORM_LIFETIME_PERMANENT, + NM_PLATFORM_LIFETIME_PERMANENT, + 0)) { + _LOGW (LOGD_IP6, "failed to add IPv6 link-local address %s", + nm_utils_inet6_ntop (&lladdr, NULL)); + } +} + static NMActStageReturn linklocal6_start (NMDevice *self) { @@ -3403,15 +3924,16 @@ linklocal6_start (NMDevice *self) linklocal6_cleanup (self); - if (linklocal6_config_is_ready (priv->ip6_config)) + if (have_ip6_address (priv->ip6_config, TRUE)) return NM_ACT_STAGE_RETURN_SUCCESS; connection = nm_device_get_connection (self); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - nm_log_dbg (LOGD_DEVICE, "[%s] linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", - nm_device_get_iface (self), method); + _LOGD (LOGD_DEVICE, "linklocal6: starting IPv6 with method '%s', but the device has no link-local addresses configured. Wait.", method); + + check_and_add_ipv6ll_addr (self); priv->linklocal6_timeout_id = g_timeout_add_seconds (5, linklocal6_timeout_cb, self); @@ -3468,12 +3990,10 @@ print_support_extended_ifa_flags (NMSettingIP6ConfigPrivacy use_tempaddr) } static void -rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device) +rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - NMConnection *connection; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int i; - NMDeviceStateReason reason; static int system_support = -1; guint ifa_flags = 0x00; @@ -3499,8 +4019,6 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device } g_return_if_fail (priv->act_request); - connection = nm_device_get_connection (device); - g_assert (connection); if (!priv->ac_ip6_config) priv->ac_ip6_config = nm_ip6_config_new (); @@ -3536,7 +4054,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.source = NM_PLATFORM_SOURCE_RDISC; + address.source = NM_IP_CONFIG_SOURCE_RDISC; address.flags = ifa_flags; nm_ip6_config_add_address (priv->ac_ip6_config, &address); @@ -3560,8 +4078,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device route.network = discovered_route->network; route.plen = discovered_route->plen; route.gateway = discovered_route->gateway; - route.source = NM_PLATFORM_SOURCE_RDISC; - route.metric = nm_device_get_priority (device); + route.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); } @@ -3591,39 +4109,99 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device } if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { - dhcp6_cleanup (device, TRUE, TRUE); + dhcp6_cleanup (self, TRUE, TRUE); priv->dhcp6_mode = rdisc->dhcp_level; - - switch (priv->dhcp6_mode) { - case NM_RDISC_DHCP_LEVEL_NONE: - break; - default: - nm_log_info (LOGD_DEVICE | LOGD_DHCP6, - "Activation (%s) Stage 3 of 5 (IP Configure Start) starting DHCPv6" - " as requested by IPv6 router...", - priv->iface); - switch (dhcp6_start (device, connection, priv->dhcp6_mode, &reason)) { - case NM_ACT_STAGE_RETURN_SUCCESS: - g_warn_if_reached (); - break; - case NM_ACT_STAGE_RETURN_POSTPONE: - return; - default: - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); - return; + if (priv->dhcp6_mode != NM_RDISC_DHCP_LEVEL_NONE) { + NMDeviceStateReason reason; + + _LOGI (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) + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } + return; } } - if (changed & NM_RDISC_CONFIG_HOP_LIMIT) { + /* hop_limit == 0 is a special value "unspecified", so do not touch + * in this case */ + if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) { char val[16]; g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit); - nm_device_ipv6_sysctl_set (device, "hop_limit", val); + nm_device_ipv6_sysctl_set (self, "hop_limit", val); + } + + if (changed & NM_RDISC_CONFIG_MTU) { + char val[16]; + + g_snprintf (val, sizeof (val), "%d", rdisc->mtu); + nm_device_ipv6_sysctl_set (self, "mtu", val); + } + + nm_device_activate_schedule_ip6_config_result (self); +} + +static void +rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + /* We don't want to stop listening for router advertisements completely, + * but instead let device activation continue activating. If an RA + * shows up later, we'll use it as long as the device is not disconnected. + */ + + _LOGD (LOGD_IP6, "timed out waiting for IPv6 router advertisement"); + if (priv->ip6_state == IP_CONF) { + /* If RA is our only source of addressing information and we don't + * ever receive one, then time out IPv6. But if there is other + * IPv6 configuration, like manual IPv6 addresses or external IPv6 + * config, consider that sufficient for IPv6 success. + */ + if (have_ip6_address (priv->ip6_config, FALSE)) + nm_device_activate_schedule_ip6_config_result (self); + else + nm_device_activate_schedule_ip6_config_timeout (self); } +} + +static gboolean +addrconf6_start_with_link_ready (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMUtilsIPv6IfaceId iid; + + g_assert (priv->rdisc); + + if (!nm_device_get_ip_iface_identifier (self, &iid)) { + _LOGW (LOGD_IP6, "failed to get interface identifier; IPv6 cannot continue"); + return FALSE; + } + nm_rdisc_set_iid (priv->rdisc, iid); + + /* Apply any manual configuration before starting RA */ + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration"); + + nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); - nm_device_activate_schedule_ip6_config_result (device); + priv->rdisc_changed_id = g_signal_connect (priv->rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (rdisc_config_changed), + self); + priv->rdisc_timeout_id = g_signal_connect (priv->rdisc, + NM_RDISC_RA_TIMEOUT, + G_CALLBACK (rdisc_ra_timeout), + self); + nm_rdisc_start (priv->rdisc); + return TRUE; } static gboolean @@ -3645,46 +4223,26 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface); if (!priv->rdisc) { - nm_log_err (LOGD_IP6, "(%s): failed to start router discovery.", ip_iface); + _LOGE (LOGD_IP6, "failed to start router discovery (%s)", ip_iface); return FALSE; } priv->rdisc_use_tempaddr = use_tempaddr; print_support_extended_ifa_flags (use_tempaddr); - if (!nm_setting_ip6_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) + if (!nm_setting_ip_config_get_may_fail (nm_connection_get_setting_ip6_config (connection))) nm_device_add_pending_action (self, PENDING_ACTION_AUTOCONF6, TRUE); /* ensure link local is ready... */ ret = linklocal6_start (self); - if (ret == NM_ACT_STAGE_RETURN_SUCCESS) - addrconf6_start_with_link_ready (self); - else - g_return_val_if_fail (ret == NM_ACT_STAGE_RETURN_POSTPONE, TRUE); - - return TRUE; -} - -static void -addrconf6_start_with_link_ready (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - g_assert (priv->rdisc); - - /* FIXME: what if interface has no lladdr, like PPP? */ - if (priv->hw_addr_len) - nm_rdisc_set_lladdr (priv->rdisc, (const char *) priv->hw_addr, priv->hw_addr_len); - - nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); - nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); - - priv->rdisc_config_changed_sigid = g_signal_connect (priv->rdisc, NM_RDISC_CONFIG_CHANGED, - G_CALLBACK (rdisc_config_changed), self); + if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { + /* success; wait for the LL address to show up */ + return TRUE; + } - nm_rdisc_start (priv->rdisc); + /* success; already have the LL address; kick off router discovery */ + g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); + return addrconf6_start_with_link_ready (self); } static void @@ -3692,10 +4250,14 @@ addrconf6_cleanup (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->rdisc_config_changed_sigid) { - g_signal_handler_disconnect (priv->rdisc, - priv->rdisc_config_changed_sigid); - priv->rdisc_config_changed_sigid = 0; + if (priv->rdisc_changed_id) { + g_signal_handler_disconnect (priv->rdisc, priv->rdisc_changed_id); + priv->rdisc_changed_id = 0; + } + + if (priv->rdisc_timeout_id) { + g_signal_handler_disconnect (priv->rdisc, priv->rdisc_timeout_id); + priv->rdisc_timeout_id = 0; } nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); @@ -3744,8 +4306,53 @@ restore_ip6_properties (NMDevice *self) gpointer key, value; g_hash_table_iter_init (&iter, priv->ip6_saved_properties); - while (g_hash_table_iter_next (&iter, &key, &value)) + while (g_hash_table_iter_next (&iter, &key, &value)) { + /* Don't touch "disable_ipv6" if we're doing userland IPv6LL */ + if (priv->nm_ipv6ll && strcmp (key, "disable_ipv6") == 0) + continue; nm_device_ipv6_sysctl_set (self, key, value); + } +} + +static inline void +set_disable_ipv6 (NMDevice *self, const char *value) +{ + /* We only touch disable_ipv6 when NM is not managing the IPv6LL address */ + if (NM_DEVICE_GET_PRIVATE (self)->nm_ipv6ll == FALSE) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", value); +} + +static inline void +set_nm_ipv6ll (NMDevice *self, gboolean enable) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ifindex = nm_device_get_ip_ifindex (self); + const char *iface = nm_device_get_ip_iface (self); + char *value; + + if (!nm_platform_check_support_user_ipv6ll ()) + return; + + priv->nm_ipv6ll = enable; + if (ifindex > 0) { + const char *detail = enable ? "enable" : "disable"; + + _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail); + if ( !nm_platform_link_set_user_ipv6ll_enabled (ifindex, enable) + && nm_platform_get_error () != NM_PLATFORM_ERROR_NOT_FOUND) + _LOGW (LOGD_IP6, "failed to %s userspace IPv6LL address handling", detail); + + if (enable) { + /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ + value = nm_platform_sysctl_get (nm_utils_ip6_property_path (iface, "disable_ipv6")); + if (g_strcmp0 (value, "0") == 0) { + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); + } + g_free (value); + } + + } } static NMSettingIP6ConfigPrivacy @@ -3838,15 +4445,11 @@ act_stage3_ip6_config_start (NMDevice *self, connection = nm_device_get_connection (self); g_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (priv->master) - g_assert_cmpstr (method, ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - - if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0 + if ( connection_ip4_method_requires_carrier (connection, NULL) && priv->is_master && !priv->carrier) { - nm_log_info (LOGD_IP6 | LOGD_DEVICE, - "(%s): IPv6 config waiting until carrier is on", ip_iface); + _LOGI (LOGD_IP6 | LOGD_DEVICE, + "IPv6 config waiting until carrier is on"); return NM_ACT_STAGE_RETURN_WAIT; } @@ -3859,23 +4462,41 @@ act_stage3_ip6_config_start (NMDevice *self, g_slist_free (slaves); if (ready_slaves == FALSE) { - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "(%s): IPv6 config waiting until slaves are ready", - ip_iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "IPv6 config waiting until slaves are ready"); return NM_ACT_STAGE_RETURN_WAIT; } } priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_NONE; + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { - if (!priv->master) + if (!priv->master) { + gboolean old_nm_ipv6ll = priv->nm_ipv6ll; + + /* When activating an IPv6 'ignore' connection we need to revert back + * to kernel IPv6LL, but the kernel won't actually assign an address + * to the interface until disable_ipv6 is bounced. + */ + set_nm_ipv6ll (self, FALSE); + if (old_nm_ipv6ll == TRUE) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); restore_ip6_properties (self); + } return NM_ACT_STAGE_RETURN_STOP; } + /* Any method past this point requires an IPv6LL address. Use NM-controlled + * IPv6LL if this is not an assumed connection, since assumed connections + * will already have IPv6 set up. + */ + if (!nm_device_uses_assumed_connection (self)) + set_nm_ipv6ll (self, TRUE); + /* Re-enable IPv6 on the interface */ - nm_device_ipv6_sysctl_set (self, "disable_ipv6", "0"); + set_disable_ipv6 (self, "0"); /* Enable/disable IPv6 Privacy Extensions. * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf), @@ -3883,10 +4504,10 @@ act_stage3_ip6_config_start (NMDevice *self, */ ip6_privacy = ip6_use_tempaddr (); if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) { - NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection); + NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6); + ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)); } ip6_privacy = use_tempaddr_clamp (ip6_privacy); @@ -3905,17 +4526,19 @@ act_stage3_ip6_config_start (NMDevice *self, } } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { priv->dhcp6_mode = NM_RDISC_DHCP_LEVEL_MANAGED; - ret = dhcp6_start (self, connection, priv->dhcp6_mode, reason); + if (!dhcp6_start (self, TRUE, reason)) { + /* IPv6 might be disabled; allow IPv4 to proceed */ + ret = NM_ACT_STAGE_RETURN_STOP; + } else + ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) { /* New blank config */ *out_config = nm_ip6_config_new (); g_assert (*out_config); ret = NM_ACT_STAGE_RETURN_SUCCESS; - } else { - nm_log_warn (LOGD_IP6, "(%s): unhandled IPv6 config method '%s'; will fail", - nm_device_get_ip_iface (self), method); - } + } else + _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method); /* Other methods (shared) aren't implemented yet */ @@ -4014,6 +4637,42 @@ nm_device_activate_stage3_ip6_start (NMDevice *self) return TRUE; } +/* + * nm_device_check_ip_failed + * + * Progress the device to appropriate state if both IPv4 and IPv6 failed + */ +static void +nm_device_check_ip_failed (NMDevice *self, gboolean may_fail) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDeviceState state; + + if ( priv->ip4_state != IP_FAIL + || priv->ip6_state != IP_FAIL) + return; + + if (nm_device_uses_assumed_connection (self)) { + /* We have assumed configuration, but couldn't + * redo it. No problem, move to check state. */ + priv->ip4_state = priv->ip6_state = IP_DONE; + state = NM_DEVICE_STATE_IP_CHECK; + } else if ( may_fail + && get_ip_config_may_fail (self, AF_INET) + && get_ip_config_may_fail (self, AF_INET6)) { + /* Couldn't start either IPv6 and IPv4 autoconfiguration, + * but both are allowed to fail. */ + state = NM_DEVICE_STATE_SECONDARIES; + } else { + /* Autoconfiguration attempted without success. */ + state = NM_DEVICE_STATE_FAILED; + } + + nm_device_state_changed (self, + state, + NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); +} + /* * nm_device_activate_stage3_ip_config_start * @@ -4025,7 +4684,6 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActiveConnection *master; NMDevice *master_device; @@ -4034,15 +4692,12 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) priv->ip4_state = priv->ip6_state = IP_WAIT; - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) started..."); nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); /* Device should be up before we can do anything with it */ - if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) { - nm_log_warn (LOGD_DEVICE, "(%s): interface %s not up for IP configuration", - iface, nm_device_get_ip_iface (self)); - } + if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); /* If the device is a slave, then we don't do any IP configuration but we * use the IP config stage to indicate to the master we're ready for @@ -4057,10 +4712,9 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) if (master) { master_device = nm_active_connection_get_device (master); if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) { - nm_log_info (LOGD_DEVICE, "Activation (%s) connection '%s' waiting on master '%s'", - nm_device_get_iface (self), - nm_connection_get_id (nm_device_get_connection (self)), - master_device ? nm_device_get_iface (master_device) : "(unknown)"); + _LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'", + nm_connection_get_id (nm_device_get_connection (self)), + master_device ? nm_device_get_iface (master_device) : "(unknown)"); } goto out; } @@ -4073,13 +4727,10 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) if (!nm_device_activate_stage3_ip6_start (self)) goto out; - if (priv->ip4_state == IP_FAIL && priv->ip6_state == IP_FAIL) { - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } + nm_device_check_ip_failed (self, TRUE); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) complete.", iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) complete."); return FALSE; } @@ -4087,8 +4738,14 @@ out: static void fw_change_zone_cb (GError *error, gpointer user_data) { - NMDevice *self = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMDevice *self; + NMDevicePrivate *priv; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = NM_DEVICE (user_data); + priv = NM_DEVICE_GET_PRIVATE (self); priv->fw_call = NULL; @@ -4097,9 +4754,7 @@ fw_change_zone_cb (GError *error, gpointer user_data) } activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); - - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 3 of 5 (IP Configure Start) scheduled.", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled."); } /* @@ -4120,15 +4775,24 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) priv = NM_DEVICE_GET_PRIVATE (self); g_return_if_fail (priv->act_request); + g_return_if_fail (!priv->fw_call); + /* Add the interface to the specified firewall zone */ connection = nm_device_get_connection (self); g_assert (connection); s_con = nm_connection_get_setting_connection (connection); zone = nm_setting_connection_get_zone (s_con); - nm_log_dbg (LOGD_DEVICE, "Activation (%s) setting firewall zone '%s'", - nm_device_get_iface (self), zone ? zone : "default"); - priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_manager, + + if (nm_device_uses_assumed_connection (self)) { + _LOGD (LOGD_DEVICE, "Activation: skip setting firewall zone '%s' for assumed device", zone ? zone : "default"); + activation_source_schedule (self, nm_device_activate_stage3_ip_config_start, 0); + _LOGI (LOGD_DEVICE, "Activation: Stage 3 of 5 (IP Configure Start) scheduled."); + return; + } + + _LOGD (LOGD_DEVICE, "Activation: setting firewall zone '%s'", zone ? zone : "default"); + priv->fw_call = nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (self), zone, FALSE, @@ -4139,7 +4803,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) static NMActStageReturn act_stage4_ip4_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - if (nm_device_ip_config_should_fail (self, FALSE)) { + if (!get_ip_config_may_fail (self, AF_INET)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -4158,17 +4822,14 @@ nm_device_activate_ip4_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) started...", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) started..."); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) @@ -4181,16 +4842,11 @@ nm_device_activate_ip4_config_timeout (gpointer user_data) priv->ip4_state = IP_FAIL; - /* If IPv4 failed and IPv6 failed, the activation fails */ - if (priv->ip6_state == IP_FAIL) - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_check_ip_failed (self, FALSE); out: - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) complete.", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) complete."); return FALSE; } @@ -4213,16 +4869,15 @@ nm_device_activate_schedule_ip4_config_timeout (NMDevice *self) activation_source_schedule (self, nm_device_activate_ip4_config_timeout, AF_INET); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 4 of 5 (IPv4 Configure Timeout) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 4 of 5 (IPv4 Configure Timeout) scheduled..."); } static NMActStageReturn act_stage4_ip6_config_timeout (NMDevice *self, NMDeviceStateReason *reason) { - if (nm_device_ip_config_should_fail (self, TRUE)) { + if (!get_ip_config_may_fail (self, AF_INET6)) { *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -4242,17 +4897,14 @@ nm_device_activate_ip6_config_timeout (gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET6); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) started...", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) started..."); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &reason); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) @@ -4265,16 +4917,11 @@ nm_device_activate_ip6_config_timeout (gpointer user_data) priv->ip6_state = IP_FAIL; - /* If IPv6 failed and IPv4 failed, the activation fails */ - if (priv->ip4_state == IP_FAIL) - nm_device_state_changed (self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + nm_device_check_ip_failed (self, FALSE); out: - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) complete.", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) complete."); return FALSE; } @@ -4297,9 +4944,8 @@ nm_device_activate_schedule_ip6_config_timeout (NMDevice *self) activation_source_schedule (self, nm_device_activate_ip6_config_timeout, AF_INET6); - nm_log_info (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 4 of 5 (IPv6 Configure Timeout) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 4 of 5 (IPv6 Configure Timeout) scheduled..."); } static void @@ -4320,16 +4966,19 @@ share_init (void) "nf_nat_sip", "nf_nat_tftp", "nf_nat_pptp", "nf_nat_h323", NULL }; char **iter; + int errsv; if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_forward", "1")) { - nm_log_err (LOGD_SHARING, "Error starting IP forwarding: (%d) %s", - errno, strerror (errno)); + errsv = errno; + nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + errsv, strerror (errsv)); return FALSE; } if (!nm_platform_sysctl_set ("/proc/sys/net/ipv4/ip_dynaddr", "1")) { - nm_log_err (LOGD_SHARING, "error starting IP forwarding: (%d) %s", - errno, strerror (errno)); + errsv = errno; + nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + errsv, strerror (errsv)); } for (iter = modules; *iter; iter++) { @@ -4339,7 +4988,7 @@ share_init (void) if (!g_spawn_sync ("/", argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, share_child_setup, NULL, NULL, NULL, &status, &error)) { - nm_log_err (LOGD_SHARING, "error loading NAT module %s: (%d) %s", + nm_log_err (LOGD_SHARING, "share: error loading NAT module %s: (%d) %s", *iter, error ? error->code : 0, (error && error->message) ? error->message : "unknown"); if (error) @@ -4412,9 +5061,8 @@ start_sharing (NMDevice *self, NMIP4Config *config) nm_act_request_set_shared (req, TRUE); if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, config, &error)) { - nm_log_err (LOGD_SHARING, "(%s/%s): failed to start dnsmasq: %s", - nm_device_get_iface (self), ip_iface, - (error && error->message) ? error->message : "(unknown)"); + _LOGE (LOGD_SHARING, "share: (%s) failed to start dnsmasq: %s", + ip_iface, (error && error->message) ? error->message : "(unknown)"); g_error_free (error); nm_act_request_set_shared (req, FALSE); return FALSE; @@ -4429,13 +5077,12 @@ start_sharing (NMDevice *self, NMIP4Config *config) static void send_arps (NMDevice *self, const char *mode_arg) { - const char *argv[] = { "/sbin/arping", mode_arg, "-q", "-I", nm_device_get_ip_iface (self), "-c", "1", NULL, NULL }; + const char *argv[] = { NULL, mode_arg, "-q", "-I", nm_device_get_ip_iface (self), "-c", "1", NULL, NULL }; int ip_arg = G_N_ELEMENTS (argv) - 2; NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; int i, num; - NMIP4Address *addr; - guint32 ipaddr; + NMIPAddress *addr; GError *error = NULL; connection = nm_device_get_connection (self); @@ -4444,24 +5091,33 @@ send_arps (NMDevice *self, const char *mode_arg) s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) return; - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); + if (num == 0) + return; + + argv[0] = nm_utils_find_helper ("arping", NULL, NULL); + if (!argv[0]) { + _LOGW (LOGD_DEVICE | LOGD_IP4, "arping could not be found; no ARPs will be sent"); + return; + } for (i = 0; i < num; i++) { - addr = nm_setting_ip4_config_get_address (s_ip4, i); - ipaddr = nm_ip4_address_get_address (addr); - argv[ip_arg] = (char *) nm_utils_inet4_ntop (ipaddr, NULL); - - nm_log_dbg (LOGD_DEVICE | LOGD_IP4, - "Running arping %s -I %s %s", - mode_arg, nm_device_get_iface (self), argv[ip_arg]); - g_spawn_async (NULL, (char **) argv, NULL, - G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, - nm_unblock_posix_signals, - NULL, NULL, &error); - if (error) { - nm_log_warn (LOGD_DEVICE | LOGD_IP4, - "Could not send ARP for local address %s: %s", - argv[ip_arg], error->message); + gs_free char *tmp_str = NULL; + gboolean success; + + addr = nm_setting_ip_config_get_address (s_ip4, i); + argv[ip_arg] = nm_ip_address_get_address (addr); + + _LOGD (LOGD_DEVICE | LOGD_IP4, + "arping: run %s", (tmp_str = g_strjoinv (" ", (char **) argv))); + success = g_spawn_async (NULL, (char **) argv, NULL, + G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + nm_unblock_posix_signals, + NULL, NULL, &error); + if (!success) { + _LOGW (LOGD_DEVICE | LOGD_IP4, + "arping: could not send ARP for local address %s: %s", + argv[ip_arg], error->message); g_clear_error (&error); } } @@ -4497,7 +5153,7 @@ arp_announce (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; int num; arp_cleanup (self); @@ -4511,7 +5167,7 @@ arp_announce (NMDevice *self) s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) return; - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); if (num == 0) return; @@ -4525,33 +5181,33 @@ nm_device_activate_ip4_config_commit (gpointer user_data) NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActRequest *req; - const char *iface, *method; + const char *method; NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + int ip_ifindex; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET); - iface = nm_device_get_iface (self); - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) started...", - iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) started..."); req = nm_device_get_act_request (self); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); - /* Device should be up before we can do anything with it */ - if (!nm_platform_link_is_up (nm_device_get_ip_ifindex (self))) { - nm_log_warn (LOGD_DEVICE, "(%s): interface %s not up for IP configuration", - iface, nm_device_get_ip_iface (self)); + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex (self); + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { + nm_platform_link_set_up (ip_ifindex); + if (!nm_platform_link_is_up (ip_ifindex)) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); } /* NULL to use the existing priv->dev_ip4_config */ if (!ip4_config_merge_and_apply (self, NULL, TRUE, &reason)) { - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 5 of 5 (IPv4 Commit) failed", - iface); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 5 of 5 (IPv4 Commit) failed"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); goto out; } @@ -4561,7 +5217,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { if (!start_sharing (self, priv->ip4_config)) { - nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IPv4 Commit) start sharing failed.", iface); + _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed."); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); goto out; } @@ -4593,8 +5249,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); out: - nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv4 Commit) complete.", - iface); + _LOGI (LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv4 Commit) complete."); return FALSE; } @@ -4605,17 +5260,16 @@ nm_device_activate_schedule_ip4_config_result (NMDevice *self, NMIP4Config *conf NMDevicePrivate *priv; g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_IP4_CONFIG (config)); priv = NM_DEVICE_GET_PRIVATE (self); g_clear_object (&priv->dev_ip4_config); - priv->dev_ip4_config = g_object_ref (config); + if (config) + priv->dev_ip4_config = g_object_ref (config); activation_source_schedule (self, nm_device_activate_ip4_config_commit, AF_INET); - nm_log_info (LOGD_DEVICE | LOGD_IP4, - "Activation (%s) Stage 5 of 5 (IPv4 Configure Commit) scheduled...", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE | LOGD_IP4, + "Activation: Stage 5 of 5 (IPv4 Configure Commit) scheduled..."); } gboolean @@ -4639,27 +5293,27 @@ nm_device_activate_ip6_config_commit (gpointer user_data) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO; NMActRequest *req; - const char *iface; NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + int ip_ifindex; /* Clear the activation source ID now that this stage has run */ activation_source_clear (self, FALSE, AF_INET6); - iface = nm_device_get_iface (self); - nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) started...", iface); + _LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) started..."); req = nm_device_get_act_request (self); g_assert (req); connection = nm_act_request_get_connection (req); g_assert (connection); - /* Device should be up before we can do anything with it */ - g_warn_if_fail (nm_platform_link_is_up (nm_device_get_ip_ifindex (self))); - - /* Allow setting MTU etc */ - if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) - NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self); + /* Interface must be IFF_UP before IP config can be applied */ + ip_ifindex = nm_device_get_ip_ifindex (self); + if (!nm_platform_link_is_up (ip_ifindex) && !nm_device_uses_assumed_connection (self)) { + nm_platform_link_set_up (ip_ifindex); + if (!nm_platform_link_is_up (ip_ifindex)) + _LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self)); + } if (ip6_config_merge_and_apply (self, TRUE, &reason)) { /* If IPv6 wasn't the first IP to complete, and DHCP was used, @@ -4686,13 +5340,12 @@ nm_device_activate_ip6_config_commit (gpointer user_data) if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE); } else { - nm_log_warn (LOGD_DEVICE | LOGD_IP6, - "Activation (%s) Stage 5 of 5 (IPv6 Commit) failed", - iface); + _LOGW (LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 5 of 5 (IPv6 Commit) failed"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } - nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) complete.", iface); + _LOG (level, LOGD_DEVICE, "Activation: Stage 5 of 5 (IPv6 Commit) complete."); return FALSE; } @@ -4705,11 +5358,16 @@ nm_device_activate_schedule_ip6_config_result (NMDevice *self) g_return_if_fail (NM_IS_DEVICE (self)); + /* If IP had previously failed, move it back to IP_CONF since we + * clearly now have configuration. + */ + if (priv->ip6_state == IP_FAIL) + priv->ip6_state = IP_CONF; + activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6); - nm_log (LOGD_DEVICE | LOGD_IP6, level, - "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...", - nm_device_get_iface (self)); + _LOG (level, LOGD_DEVICE | LOGD_IP6, + "Activation: Stage 5 of 5 (IPv6 Commit) scheduled..."); } gboolean @@ -4775,7 +5433,7 @@ _update_ip4_address (NMDevice *self) fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_err (LOGD_IP4, "couldn't open control socket."); + _LOGE (LOGD_IP4, "couldn't open control socket."); return; } @@ -4790,17 +5448,17 @@ _update_ip4_address (NMDevice *self) } gboolean -nm_device_get_is_nm_owned (NMDevice *device) +nm_device_get_is_nm_owned (NMDevice *self) { - return NM_DEVICE_GET_PRIVATE (device)->is_nm_owned; + return NM_DEVICE_GET_PRIVATE (self)->is_nm_owned; } void -nm_device_set_nm_owned (NMDevice *device) +nm_device_set_nm_owned (NMDevice *self) { - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - NM_DEVICE_GET_PRIVATE (device)->is_nm_owned = TRUE; + NM_DEVICE_GET_PRIVATE (self)->is_nm_owned = TRUE; } /* @@ -4814,6 +5472,7 @@ static gboolean delete_on_deactivate_link_delete (gpointer user_data) { DeleteOnDeactivateData *data = user_data; + NMDevice *self = data->device; if (data->device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (data->device); @@ -4822,8 +5481,8 @@ delete_on_deactivate_link_delete (gpointer user_data) priv->delete_on_deactivate_data = NULL; } - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", + data->ifindex, data->idle_add_id); nm_platform_link_delete (data->ifindex); g_free (data); return FALSE; @@ -4841,8 +5500,8 @@ delete_on_deactivate_unschedule (NMDevice *self) g_source_remove (data->idle_add_id); g_object_remove_weak_pointer (G_OBJECT (self), (void **) &data->device); - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", - data->ifindex, data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", + data->ifindex, data->idle_add_id); g_free (data); } } @@ -4857,6 +5516,8 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) return; if (!priv->is_nm_owned) return; + if (priv->queued_act_request) + return; if (!nm_device_is_software (self)) return; if (nm_device_get_state (self) == NM_DEVICE_STATE_UNMANAGED) @@ -4872,17 +5533,17 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex) data->idle_add_id = g_idle_add (delete_on_deactivate_link_delete, data); priv->delete_on_deactivate_data = data; - nm_log_dbg (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d for [%s] (id=%u)", - ifindex, nm_device_get_iface (self), data->idle_add_id); + _LOGD (LOGD_DEVICE, "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)", + ifindex, data->idle_add_id); } static void -disconnect_cb (NMDevice *device, +disconnect_cb (NMDevice *self, DBusGMethodInvocation *context, GError *error, gpointer user_data) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GError *local = NULL; if (error) { @@ -4898,9 +5559,9 @@ disconnect_cb (NMDevice *device, dbus_g_method_return_error (context, local); g_error_free (local); } else { - priv->autoconnect = FALSE; + nm_device_set_autoconnect (self, FALSE); - nm_device_state_changed (device, + nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_USER_REQUESTED); dbus_g_method_return (context); @@ -4908,12 +5569,12 @@ disconnect_cb (NMDevice *device, } static void -impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) +impl_device_disconnect (NMDevice *self, DBusGMethodInvocation *context) { NMConnection *connection; GError *error = NULL; - if (NM_DEVICE_GET_PRIVATE (device)->act_request == NULL) { + if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) { error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, "This device is not active"); @@ -4922,11 +5583,11 @@ impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) return; } - connection = nm_device_get_connection (device); + connection = nm_device_get_connection (self); g_assert (connection); /* Ask the manager to authenticate this request for us */ - g_signal_emit (device, signals[AUTH_REQUEST], 0, + g_signal_emit (self, signals[AUTH_REQUEST], 0, context, connection, NM_AUTH_PERMISSION_NETWORK_CONTROL, @@ -4936,22 +5597,61 @@ impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) } static void -_device_activate (NMDevice *self, NMActRequest *req) +delete_cb (NMDevice *self, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) { - NMDevicePrivate *priv; - NMConnection *connection; - - g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_ACT_REQUEST (req)); - - priv = NM_DEVICE_GET_PRIVATE (self); + if (error) { + dbus_g_method_return_error (context, error); + return; + } - connection = nm_act_request_get_connection (req); - g_assert (connection); + /* Authorized */ + nm_platform_link_delete (nm_device_get_ifindex (self)); + dbus_g_method_return (context); +} - nm_log_info (LOGD_DEVICE, "Activation (%s) starting connection '%s'", - nm_device_get_iface (self), - nm_connection_get_id (connection)); +static void +impl_device_delete (NMDevice *self, DBusGMethodInvocation *context) +{ + GError *error = NULL; + + if (!nm_device_is_software (self)) { + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device"); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Ask the manager to authenticate this request for us */ + g_signal_emit (self, signals[AUTH_REQUEST], 0, + context, + NULL, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + delete_cb, + NULL); +} + +static void +_device_activate (NMDevice *self, NMActRequest *req) +{ + NMDevicePrivate *priv; + NMConnection *connection; + + g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail (NM_IS_ACT_REQUEST (req)); + + priv = NM_DEVICE_GET_PRIVATE (self); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + + _LOGI (LOGD_DEVICE, "Activation: starting connection '%s'", + nm_connection_get_id (connection)); delete_on_deactivate_unschedule (self); @@ -4986,8 +5686,7 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req) priv->queued_act_request = g_object_ref (req); /* Deactivate existing activation request first */ - nm_log_info (LOGD_DEVICE, "(%s): disconnecting for new activation request.", - nm_device_get_iface (self)); + _LOGI (LOGD_DEVICE, "disconnecting for new activation request."); nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NONE); @@ -5000,14 +5699,14 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req) * */ gboolean -nm_device_is_activating (NMDevice *device) +nm_device_is_activating (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState state; - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - state = nm_device_get_state (device); + state = nm_device_get_state (self); if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES) return TRUE; @@ -5021,7 +5720,7 @@ nm_device_is_activating (NMDevice *device) /* IP Configuration stuff */ -NMDHCP4Config * +NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -5041,6 +5740,7 @@ nm_device_get_ip4_config (NMDevice *self) static gboolean nm_device_set_ip4_config (NMDevice *self, NMIP4Config *new_config, + guint32 default_route_metric, gboolean commit, NMDeviceStateReason *reason) { @@ -5062,7 +5762,12 @@ nm_device_set_ip4_config (NMDevice *self, /* Always commit to nm-platform to update lifetimes */ if (commit && new_config) { - success = nm_ip4_config_commit (new_config, ip_ifindex); + gboolean assumed = nm_device_uses_assumed_connection (self); + + /* for assumed devices we set the device_route_metric to the default which will + * stop nm_platform_ip4_address_sync() to replace the device routes. */ + success = nm_ip4_config_commit (new_config, ip_ifindex, + assumed ? NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE : default_route_metric); if (!success) reason_local = NM_DEVICE_STATE_REASON_CONFIG_FAILED; } @@ -5073,8 +5778,8 @@ nm_device_set_ip4_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip4_config_replace (old_config, new_config, &has_changes); if (has_changes) { - nm_log_dbg (LOGD_IP4, "(%s): update IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP4, "update IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (old_config)); } } else { has_changes = TRUE; @@ -5085,18 +5790,20 @@ nm_device_set_ip4_config (NMDevice *self, nm_ip4_config_export (new_config); } - nm_log_dbg (LOGD_IP4, "(%s): set IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (new_config)); + _LOGD (LOGD_IP4, "set IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (new_config)); } } else if (old_config) { has_changes = TRUE; priv->ip4_config = NULL; - nm_log_dbg (LOGD_IP4, "(%s): clear IP4Config instance (%s)", - ip_iface, nm_ip4_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP4, "clear IP4Config instance (%s)", + nm_ip4_config_get_dbus_path (old_config)); /* Device config is invalid if combined config is invalid */ g_clear_object (&priv->dev_ip4_config); } + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + if (has_changes) { _update_ip4_address (self); @@ -5107,7 +5814,7 @@ nm_device_set_ip4_config (NMDevice *self, if (old_config != priv->ip4_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip4; @@ -5128,9 +5835,9 @@ nm_device_set_ip4_config (NMDevice *self, } void -nm_device_set_vpn4_config (NMDevice *device, NMIP4Config *config) +nm_device_set_vpn4_config (NMDevice *self, NMIP4Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->vpn4_config == config) return; @@ -5140,10 +5847,25 @@ nm_device_set_vpn4_config (NMDevice *device, NMIP4Config *config) priv->vpn4_config = g_object_ref (config); /* NULL to use existing configs */ - if (!ip4_config_merge_and_apply (device, NULL, TRUE, NULL)) { - nm_log_warn (LOGD_IP4, "(%s): failed to set VPN routes for device", - nm_device_get_ip_iface (device)); - } + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed to set VPN routes for device"); +} + +void +nm_device_set_wwan_ip4_config (NMDevice *self, NMIP4Config *config) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->wwan_ip4_config == config) + return; + + g_clear_object (&priv->wwan_ip4_config); + if (config) + priv->wwan_ip4_config = g_object_ref (config); + + /* NULL to use existing configs */ + if (!ip4_config_merge_and_apply (self, NULL, TRUE, NULL)) + _LOGW (LOGD_IP4, "failed to set WWAN IPv4 configuration"); } static gboolean @@ -5181,8 +5903,8 @@ nm_device_set_ip6_config (NMDevice *self, * this causes a re-read and reset. This should only happen for relevant changes */ nm_ip6_config_replace (old_config, new_config, &has_changes); if (has_changes) { - nm_log_dbg (LOGD_IP6, "(%s): update IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP6, "update IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (old_config)); } } else { has_changes = TRUE; @@ -5193,16 +5915,18 @@ nm_device_set_ip6_config (NMDevice *self, nm_ip6_config_export (new_config); } - nm_log_dbg (LOGD_IP4, "(%s): set IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (new_config)); + _LOGD (LOGD_IP4, "set IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (new_config)); } } else if (old_config) { has_changes = TRUE; priv->ip6_config = NULL; - nm_log_dbg (LOGD_IP6, "(%s): clear IP6Config instance (%s)", - ip_iface, nm_ip6_config_get_dbus_path (old_config)); + _LOGD (LOGD_IP6, "clear IP6Config instance (%s)", + nm_ip6_config_get_dbus_path (old_config)); } + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + if (has_changes) { if (old_config != priv->ip6_config) g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG); @@ -5211,7 +5935,7 @@ nm_device_set_ip6_config (NMDevice *self, if (old_config != priv->ip6_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip6; @@ -5232,9 +5956,9 @@ nm_device_set_ip6_config (NMDevice *self, } void -nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config) +nm_device_set_vpn6_config (NMDevice *self, NMIP6Config *config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->vpn6_config == config) return; @@ -5244,13 +5968,28 @@ nm_device_set_vpn6_config (NMDevice *device, NMIP6Config *config) priv->vpn6_config = g_object_ref (config); /* NULL to use existing configs */ - if (!ip6_config_merge_and_apply (device, TRUE, NULL)) { - nm_log_warn (LOGD_IP6, "(%s): failed to set VPN routes for device", - nm_device_get_ip_iface (device)); - } + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to set VPN routes for device"); +} + +void +nm_device_set_wwan_ip6_config (NMDevice *self, NMIP6Config *config) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->wwan_ip6_config == config) + return; + + g_clear_object (&priv->wwan_ip6_config); + if (config) + priv->wwan_ip6_config = g_object_ref (config); + + /* NULL to use existing configs */ + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "failed to set WWAN IPv6 configuration"); } -NMDHCP6Config * +NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -5336,16 +6075,7 @@ ip_check_gw_ping_cleanup (NMDevice *self) } if (priv->gw_ping.pid) { - guint count = 20; - int status; - - kill (priv->gw_ping.pid, SIGKILL); - do { - if (waitpid (priv->gw_ping.pid, &status, WNOHANG) != 0) - break; - g_usleep (G_USEC_PER_SEC / 20); - } while (count--); - + nm_utils_kill_child_async (priv->gw_ping.pid, SIGTERM, priv->gw_ping.log_domain, "ping", 1000, NULL, NULL); priv->gw_ping.pid = 0; } } @@ -5355,7 +6085,6 @@ ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - const char *iface; guint log_domain = priv->gw_ping.log_domain; if (!priv->gw_ping.watch) @@ -5363,17 +6092,15 @@ ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data) priv->gw_ping.watch = 0; priv->gw_ping.pid = 0; - iface = nm_device_get_iface (self); - if (WIFEXITED (status)) { if (WEXITSTATUS (status) == 0) - nm_log_dbg (log_domain, "(%s): gateway ping succeeded", iface); + _LOGD (log_domain, "ping: gateway ping succeeded"); else { - nm_log_warn (log_domain, "(%s): gateway ping failed with error code %d", - iface, WEXITSTATUS (status)); + _LOGW (log_domain, "ping: gateway ping failed with error code %d", + WEXITSTATUS (status)); } } else - nm_log_warn (log_domain, "(%s): ping stopped unexpectedly with status %d", iface, status); + _LOGW (log_domain, "ping: stopped unexpectedly with status %d", status); /* We've got connectivity, proceed to pre_up */ ip_check_gw_ping_cleanup (self); @@ -5388,8 +6115,7 @@ ip_check_ping_timeout_cb (gpointer user_data) priv->gw_ping.timeout = 0; - nm_log_warn (priv->gw_ping.log_domain, "(%s): gateway ping timed out", - nm_device_get_iface (self)); + _LOGW (priv->gw_ping.log_domain, "ping: gateway ping timed out"); ip_check_gw_ping_cleanup (self); ip_check_pre_up (self); @@ -5406,7 +6132,8 @@ spawn_ping (NMDevice *self, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const char *args[] = { binary, "-I", nm_device_get_ip_iface (self), "-c", "1", "-w", NULL, address, NULL }; GError *error = NULL; - char *str_timeout, *cmd; + char *str_timeout; + gs_free char *tmp_str = NULL; gboolean success; g_return_val_if_fail (priv->gw_ping.watch == 0, FALSE); @@ -5414,13 +6141,8 @@ spawn_ping (NMDevice *self, args[6] = str_timeout = g_strdup_printf ("%u", timeout); - if (nm_logging_enabled (LOGL_DEBUG, log_domain)) { - cmd = g_strjoinv (" ", (gchar **) args); - nm_log_dbg (log_domain, "(%s): running '%s'", - nm_device_get_iface (self), - cmd); - g_free (cmd); - } + _LOGD (log_domain, "ping: running '%s'", + (tmp_str = g_strjoinv (" ", (gchar **) args))); success = g_spawn_async ("/", (gchar **) args, @@ -5435,7 +6157,7 @@ spawn_ping (NMDevice *self, priv->gw_ping.watch = g_child_watch_add (priv->gw_ping.pid, ip_check_ping_watch_cb, self); priv->gw_ping.timeout = g_timeout_add_seconds (timeout + 1, ip_check_ping_timeout_cb, self); } else { - nm_log_warn (log_domain, "could not spawn %s: %s", binary, error->message); + _LOGW (log_domain, "ping: could not spawn %s: %s", binary, error->message); g_clear_error (&error); } @@ -5471,7 +6193,7 @@ nm_device_start_ip_check (NMDevice *self) timeout = nm_setting_connection_get_gateway_ping_timeout (s_con); if (timeout) { - if (priv->ip4_state == IP_DONE) { + if (priv->ip4_config && priv->ip4_state == IP_DONE) { guint gw = 0; ping_binary = "/usr/bin/ping"; @@ -5524,9 +6246,9 @@ nm_device_is_up (NMDevice *self) } static gboolean -is_up (NMDevice *device) +is_up (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); return ifindex > 0 ? nm_platform_link_is_up (ifindex) : TRUE; } @@ -5539,7 +6261,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - nm_log_dbg (LOGD_HW, "(%s): bringing up device.", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "bringing up device."); if (NM_DEVICE_GET_CLASS (self)->bring_up) { if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware)) @@ -5561,9 +6283,9 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) if (!device_is_up) { if (block) - nm_log_warn (LOGD_HW, "(%s): device not up after timeout!", nm_device_get_iface (self)); + _LOGW (LOGD_HW, "device not up after timeout!"); else - nm_log_dbg (LOGD_HW, "(%s): device not up immediately", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "device not up immediately"); return FALSE; } @@ -5589,18 +6311,18 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) } static void -check_carrier (NMDevice *device) +check_carrier (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); - if (!device_has_capability (device, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) - nm_device_set_carrier (device, nm_platform_link_is_connected (ifindex)); + if (!device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER)) + nm_device_set_carrier (self, nm_platform_link_is_connected (ifindex)); } static gboolean -bring_up (NMDevice *device, gboolean *no_firmware) +bring_up (NMDevice *self, gboolean *no_firmware) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); gboolean result; if (ifindex <= 0) { @@ -5614,8 +6336,8 @@ bring_up (NMDevice *device, gboolean *no_firmware) *no_firmware = nm_platform_get_error () == NM_PLATFORM_ERROR_NO_FIRMWARE; /* Store carrier immediately. */ - if (result && device_has_capability (device, NM_DEVICE_CAP_CARRIER_DETECT)) - check_carrier (device); + if (result && device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) + check_carrier (self); return result; } @@ -5627,7 +6349,7 @@ nm_device_take_down (NMDevice *self, gboolean block) g_return_if_fail (NM_IS_DEVICE (self)); - nm_log_dbg (LOGD_HW, "(%s): taking down device.", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "taking down device."); if (NM_DEVICE_GET_CLASS (self)->take_down) { if (!NM_DEVICE_GET_CLASS (self)->take_down (self)) @@ -5649,22 +6371,22 @@ nm_device_take_down (NMDevice *self, gboolean block) if (device_is_up) { if (block) - nm_log_warn (LOGD_HW, "(%s): device not down after timeout!", nm_device_get_iface (self)); + _LOGW (LOGD_HW, "device not down after timeout!"); else - nm_log_dbg (LOGD_HW, "(%s): device not down immediately", nm_device_get_iface (self)); + _LOGD (LOGD_HW, "device not down immediately"); } } static gboolean -take_down (NMDevice *device) +take_down (NMDevice *self) { - int ifindex = nm_device_get_ip_ifindex (device); + int ifindex = nm_device_get_ip_ifindex (self); if (ifindex > 0) return nm_platform_link_set_down (ifindex); /* devices without ifindex are always up. */ - nm_log_dbg (LOGD_HW, "(%s): cannot take down device without ifindex", nm_device_get_iface (device)); + _LOGD (LOGD_HW, "cannot take down device without ifindex"); return FALSE; } @@ -5689,11 +6411,11 @@ nm_device_get_firmware_missing (NMDevice *self) } static NMIP4Config * -find_ip4_lease_config (NMDevice *device, +find_ip4_lease_config (NMDevice *self, NMConnection *connection, NMIP4Config *ext_ip4_config) { - const char *ip_iface = nm_device_get_ip_iface (device); + const char *ip_iface = nm_device_get_ip_iface (self); GSList *leases, *liter; NMIP4Config *found = NULL; @@ -5703,7 +6425,8 @@ find_ip4_lease_config (NMDevice *device, leases = nm_dhcp_manager_get_lease_ip_configs (nm_dhcp_manager_get (), ip_iface, nm_connection_get_uuid (connection), - FALSE); + FALSE, + nm_device_get_ip4_route_metric (self)); for (liter = leases; liter && !found; liter = liter->next) { NMIP4Config *lease_config = liter->data; const NMPlatformIP4Address *address = nm_ip4_config_get_address (lease_config, 0); @@ -5722,13 +6445,13 @@ find_ip4_lease_config (NMDevice *device, } static void -capture_lease_config (NMDevice *device, +capture_lease_config (NMDevice *self, NMIP4Config *ext_ip4_config, NMIP4Config **out_ip4_config, NMIP6Config *ext_ip6_config, NMIP6Config **out_ip6_config) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const GSList *connections, *citer; guint i; gboolean dhcp_used = FALSE; @@ -5767,13 +6490,13 @@ capture_lease_config (NMDevice *device, NMConnection *candidate = citer->data; const char *method; - if (!nm_device_check_connection_compatible (device, candidate)) + if (!nm_device_check_connection_compatible (self, candidate)) continue; /* IPv4 leases */ method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG); if (out_ip4_config && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { - *out_ip4_config = find_ip4_lease_config (device, candidate, ext_ip4_config); + *out_ip4_config = find_ip4_lease_config (self, candidate, ext_ip4_config); if (*out_ip4_config) return; } @@ -5805,7 +6528,8 @@ update_ip_config (NMDevice *self, gboolean initial) /* IPv4 */ g_clear_object (&priv->ext_ip4_config); priv->ext_ip4_config = nm_ip4_config_capture (ifindex, capture_resolv_conf); - + priv->ext_ip4_config_had_any_addresses = ( priv->ext_ip4_config + && nm_ip4_config_get_num_addresses (priv->ext_ip4_config) > 0); if (priv->ext_ip4_config) { if (initial) { g_clear_object (&priv->dev_ip4_config); @@ -5815,6 +6539,8 @@ update_ip_config (NMDevice *self, gboolean initial) nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config); if (priv->vpn4_config) nm_ip4_config_subtract (priv->ext_ip4_config, priv->vpn4_config); + if (priv->wwan_ip4_config) + nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config); ip4_config_merge_and_apply (self, NULL, FALSE, NULL); } @@ -5822,16 +6548,20 @@ update_ip_config (NMDevice *self, gboolean initial) /* IPv6 */ g_clear_object (&priv->ext_ip6_config); priv->ext_ip6_config = nm_ip6_config_capture (ifindex, capture_resolv_conf, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + priv->ext_ip6_config_had_any_addresses = ( priv->ext_ip6_config + && nm_ip6_config_get_num_addresses (priv->ext_ip6_config) > 0); if (priv->ext_ip6_config) { /* Check this before modifying ext_ip6_config */ linklocal6_just_completed = priv->linklocal6_timeout_id && - linklocal6_config_is_ready (priv->ext_ip6_config); + have_ip6_address (priv->ext_ip6_config, TRUE); 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->wwan_ip6_config) + nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config); if (priv->vpn6_config) nm_ip6_config_subtract (priv->ext_ip6_config, priv->vpn6_config); @@ -5847,9 +6577,9 @@ update_ip_config (NMDevice *self, gboolean initial) } void -nm_device_capture_initial_config (NMDevice *dev) +nm_device_capture_initial_config (NMDevice *self) { - update_ip_config (dev, TRUE); + update_ip_config (self, TRUE); } static gboolean @@ -5864,22 +6594,33 @@ queued_ip_config_change (gpointer user_data) priv->queued_ip_config_id = 0; update_ip_config (self, FALSE); + + /* If no IPv6 link-local address exists but other addresses do then we + * must add the LL address to remain conformant with RFC 3513 chapter 2.1 + * ("Addressing Model"): "All interfaces are required to have at least + * one link-local unicast address". + */ + if (priv->ip6_config && nm_ip6_config_get_num_addresses (priv->ip6_config)) + check_and_add_ipv6ll_addr (self); + return FALSE; } static void -device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, NMPlatformSignalChangeType change_type, NMPlatformReason reason, gpointer user_data) +device_ip_changed (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDevice *self) { - NMDevice *self = user_data; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (nm_device_get_ip_ifindex (self) == ifindex) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (!priv->queued_ip_config_id) priv->queued_ip_config_id = g_idle_add (queued_ip_config_change, self); - nm_log_dbg (LOGD_DEVICE, "(%s): queued IP config change", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "queued IP config change"); } } @@ -5889,8 +6630,7 @@ nm_device_queued_ip_config_change_clear (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->queued_ip_config_id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued IP config change", - nm_device_get_iface (self)); + _LOGD (LOGD_DEVICE, "clearing queued IP config change"); g_source_remove (priv->queued_ip_config_id); priv->queued_ip_config_id = 0; } @@ -5898,19 +6638,19 @@ nm_device_queued_ip_config_change_clear (NMDevice *self) /** * nm_device_get_managed(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is managed */ gboolean -nm_device_get_managed (NMDevice *device) +nm_device_get_managed (NMDevice *self) { NMDevicePrivate *priv; gboolean managed; - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); /* Return the composite of all managed flags. However, if the device * is a default-unmanaged device, and would be managed except for the @@ -5926,30 +6666,30 @@ nm_device_get_managed (NMDevice *device) /** * nm_device_get_unmanaged_flag(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is unmanaged for @flag. */ gboolean -nm_device_get_unmanaged_flag (NMDevice *device, NMUnmanagedFlags flag) +nm_device_get_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag) { - return NM_DEVICE_GET_PRIVATE (device)->unmanaged_flags & flag; + return NM_FLAGS_ANY (NM_DEVICE_GET_PRIVATE (self)->unmanaged_flags, flag); } /** * nm_device_get_default_unmanaged(): - * @device: the #NMDevice + * @self: the #NMDevice * * Returns: %TRUE if the device is by default unmanaged */ static gboolean -nm_device_get_default_unmanaged (NMDevice *device) +nm_device_get_default_unmanaged (NMDevice *self) { - return nm_device_get_unmanaged_flag (device, NM_UNMANAGED_DEFAULT); + return nm_device_get_unmanaged_flag (self, NM_UNMANAGED_DEFAULT); } void -nm_device_set_unmanaged (NMDevice *device, +nm_device_set_unmanaged (NMDevice *self, NMUnmanagedFlags flag, gboolean unmanaged, NMDeviceStateReason reason) @@ -5957,42 +6697,40 @@ nm_device_set_unmanaged (NMDevice *device, NMDevicePrivate *priv; gboolean was_managed, now_managed; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); g_return_if_fail (flag <= NM_UNMANAGED_LAST); - priv = NM_DEVICE_GET_PRIVATE (device); + priv = NM_DEVICE_GET_PRIVATE (self); - was_managed = nm_device_get_managed (device); + was_managed = nm_device_get_managed (self); if (unmanaged) priv->unmanaged_flags |= flag; else priv->unmanaged_flags &= ~flag; - now_managed = nm_device_get_managed (device); + now_managed = nm_device_get_managed (self); if (was_managed != now_managed) { - nm_log_dbg (LOGD_DEVICE, "(%s): now %s", - nm_device_get_iface (device), - unmanaged ? "unmanaged" : "managed"); + _LOGD (LOGD_DEVICE, "now %s", unmanaged ? "unmanaged" : "managed"); - g_object_notify (G_OBJECT (device), NM_DEVICE_MANAGED); + g_object_notify (G_OBJECT (self), NM_DEVICE_MANAGED); if (unmanaged) - nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, reason); + nm_device_state_changed (self, NM_DEVICE_STATE_UNMANAGED, reason); else - nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, reason); + nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, reason); } } void -nm_device_set_unmanaged_quitting (NMDevice *device) +nm_device_set_unmanaged_quitting (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); /* It's OK to block here because we're quitting */ - if (nm_device_is_activating (device) || priv->state == NM_DEVICE_STATE_ACTIVATED) - _set_state_full (device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE); + if (nm_device_is_activating (self) || priv->state == NM_DEVICE_STATE_ACTIVATED) + _set_state_full (self, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_REMOVED, TRUE); - nm_device_set_unmanaged (device, + nm_device_set_unmanaged (self, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED); @@ -6000,26 +6738,26 @@ nm_device_set_unmanaged_quitting (NMDevice *device) /** * nm_device_set_initial_unmanaged_flag(): - * @device: the #NMDevice + * @self: the #NMDevice * @flag: an #NMUnmanagedFlag * @unmanaged: %TRUE or %FALSE to set or clear @flag * - * Like nm_device_set_unmanaged() but must be set before the device is exported - * and does not trigger state changes. Should only be used when initializing - * a device. + * Like nm_device_set_unmanaged(), but must be set before the device is + * initialized by nm_device_finish_init(), and does not trigger state changes. + * Should only be used when initializing a device. */ void -nm_device_set_initial_unmanaged_flag (NMDevice *device, +nm_device_set_initial_unmanaged_flag (NMDevice *self, NMUnmanagedFlags flag, gboolean unmanaged) { NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); g_return_if_fail (flag <= NM_UNMANAGED_LAST); - priv = NM_DEVICE_GET_PRIVATE (device); - g_return_if_fail (priv->path == NULL); + priv = NM_DEVICE_GET_PRIVATE (self); + g_return_if_fail (priv->initialized == FALSE); if (unmanaged) priv->unmanaged_flags |= flag; @@ -6028,60 +6766,54 @@ nm_device_set_initial_unmanaged_flag (NMDevice *device, } void -nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout) +nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout) { - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - NM_DEVICE_GET_PRIVATE (device)->dhcp_timeout = timeout; + NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout; } void -nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr) +nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) { NMDevicePrivate *priv; - g_return_if_fail (NM_IS_DEVICE (device)); - - priv = NM_DEVICE_GET_PRIVATE (device); + g_return_if_fail (NM_IS_DEVICE (self)); + g_return_if_fail (!addr || nm_utils_hwaddr_valid (addr, ETH_ALEN)); - if (priv->dhcp_anycast_address) { - g_byte_array_free (priv->dhcp_anycast_address, TRUE); - priv->dhcp_anycast_address = NULL; - } + priv = NM_DEVICE_GET_PRIVATE (self); - if (addr) { - priv->dhcp_anycast_address = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (priv->dhcp_anycast_address, addr, ETH_ALEN); - } + g_free (priv->dhcp_anycast_address); + priv->dhcp_anycast_address = g_strdup (addr); } /** * nm_device_connection_is_available(): - * @device: the #NMDevice + * @self: the #NMDevice * @connection: the #NMConnection to check for availability * @allow_device_override: set to %TRUE to let the device do specific checks * - * Check if @connection is available to be activated on @device. Normally this - * only checks if the connection is in @device's AvailableConnections property. + * Check if @connection is available to be activated on @self. Normally this + * only checks if the connection is in @self's AvailableConnections property. * If @allow_device_override is %TRUE then the device is asked to do specific * checks that may bypass the AvailableConnections property. * - * Returns: %TRUE if @connection can be activated on @device + * Returns: %TRUE if @connection can be activated on @self */ gboolean -nm_device_connection_is_available (NMDevice *device, +nm_device_connection_is_available (NMDevice *self, NMConnection *connection, gboolean allow_device_override) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean available = FALSE; - if (nm_device_get_default_unmanaged (device) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { + if (nm_device_get_default_unmanaged (self) && (priv->state == NM_DEVICE_STATE_UNMANAGED)) { /* default-unmanaged devices in UNMANAGED state have no available connections * so we must manually check whether the connection is available here. */ - if ( nm_device_check_connection_compatible (device, connection) - && NM_DEVICE_GET_CLASS (device)->check_connection_available (device, connection, NULL)) + if ( nm_device_check_connection_compatible (self, connection) + && NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, NULL)) return TRUE; } @@ -6092,32 +6824,33 @@ nm_device_connection_is_available (NMDevice *device, * activating but the network isn't available let the device recheck * availability. */ - if ( nm_device_check_connection_compatible (device, connection) - && NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden) - available = NM_DEVICE_GET_CLASS (device)->check_connection_available_wifi_hidden (device, connection); + if ( nm_device_check_connection_compatible (self, connection) + && NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden) + available = NM_DEVICE_GET_CLASS (self)->check_connection_available_wifi_hidden (self, connection); } return available; } static void -_signal_available_connections_changed (NMDevice *device) +_signal_available_connections_changed (NMDevice *self) { - g_object_notify (G_OBJECT (device), NM_DEVICE_AVAILABLE_CONNECTIONS); + g_object_notify (G_OBJECT (self), NM_DEVICE_AVAILABLE_CONNECTIONS); } static void -_clear_available_connections (NMDevice *device, gboolean do_signal) +_clear_available_connections (NMDevice *self, gboolean do_signal) { - g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (device)->available_connections); + g_hash_table_remove_all (NM_DEVICE_GET_PRIVATE (self)->available_connections); if (do_signal == TRUE) - _signal_available_connections_changed (device); + _signal_available_connections_changed (self); } static gboolean _try_add_available_connection (NMDevice *self, NMConnection *connection) { - if (nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED) + if ( nm_device_get_state (self) < NM_DEVICE_STATE_DISCONNECTED + && !nm_device_get_default_unmanaged (self)) return FALSE; if (nm_device_check_connection_compatible (self, connection)) { @@ -6132,98 +6865,49 @@ _try_add_available_connection (NMDevice *self, NMConnection *connection) } static gboolean -_del_available_connection (NMDevice *device, NMConnection *connection) -{ - return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (device)->available_connections, connection); -} - -static gboolean -connection_requires_carrier (NMConnection *connection) +_del_available_connection (NMDevice *self, NMConnection *connection) { - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - const char *method; - gboolean ip4_carrier_wanted = FALSE, ip6_carrier_wanted = FALSE; - gboolean ip4_used = FALSE, ip6_used = FALSE; - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if ( strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) != 0 - && strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0) { - ip4_carrier_wanted = TRUE; - - /* If IPv4 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv6 method. - */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4)) - return TRUE; - } - ip4_used = (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) != 0); - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) != 0 - && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0) { - ip6_carrier_wanted = TRUE; - - /* If IPv6 wants a carrier and cannot fail, the whole connection - * requires a carrier regardless of the IPv4 method. - */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6)) - return TRUE; - } - ip6_used = (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) != 0); - - /* If an IP version wants a carrier and and the other IP version isn't - * used, the connection requires carrier since it will just fail without one. - */ - if (ip4_carrier_wanted && !ip6_used) - return TRUE; - if (ip6_carrier_wanted && !ip4_used) - return TRUE; - - /* If both want a carrier, the whole connection wants a carrier */ - return ip4_carrier_wanted && ip6_carrier_wanted; + return g_hash_table_remove (NM_DEVICE_GET_PRIVATE (self)->available_connections, connection); } static gboolean -check_connection_available (NMDevice *device, +check_connection_available (NMDevice *self, NMConnection *connection, const char *specific_object) { /* Connections which require a network connection are not available when * the device has no carrier, even with ignore-carrer=TRUE. */ - if (NM_DEVICE_GET_PRIVATE (device)->carrier == FALSE) + if (NM_DEVICE_GET_PRIVATE (self)->carrier == FALSE) return connection_requires_carrier (connection) ? FALSE : TRUE; return TRUE; } void -nm_device_recheck_available_connections (NMDevice *device) +nm_device_recheck_available_connections (NMDevice *self) { NMDevicePrivate *priv; const GSList *connections, *iter; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE(device); + priv = NM_DEVICE_GET_PRIVATE(self); if (priv->con_provider) { - _clear_available_connections (device, FALSE); + _clear_available_connections (self, FALSE); connections = nm_connection_provider_get_connections (priv->con_provider); for (iter = connections; iter; iter = g_slist_next (iter)) - _try_add_available_connection (device, NM_CONNECTION (iter->data)); + _try_add_available_connection (self, NM_CONNECTION (iter->data)); - _signal_available_connections_changed (device); + _signal_available_connections_changed (self); } } /** * nm_device_get_available_connections: - * @device: the #NMDevice + * @self: the #NMDevice * @specific_object: a specific object path if any * * Returns a list of connections available to activate on the device, taking @@ -6233,9 +6917,9 @@ nm_device_recheck_available_connections (NMDevice *device) * Returns: caller-owned #GPtrArray of #NMConnections */ GPtrArray * -nm_device_get_available_connections (NMDevice *device, const char *specific_object) +nm_device_get_available_connections (NMDevice *self, const char *specific_object) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GHashTableIter iter; guint num_available; NMConnection *connection = NULL; @@ -6250,7 +6934,7 @@ nm_device_get_available_connections (NMDevice *device, const char *specific_obje * compatible with it. */ if ( !specific_object - || NM_DEVICE_GET_CLASS (device)->check_connection_available (device, connection, specific_object)) + || NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, specific_object)) g_ptr_array_add (array, connection); } } @@ -6286,14 +6970,14 @@ cp_connection_updated (NMConnectionProvider *cp, NMConnection *connection, gpoin } gboolean -nm_device_supports_vlans (NMDevice *device) +nm_device_supports_vlans (NMDevice *self) { - return nm_platform_link_supports_vlans (nm_device_get_ifindex (device)); + return nm_platform_link_supports_vlans (nm_device_get_ifindex (self)); } /** * nm_device_add_pending_action(): - * @device: the #NMDevice to add the pending action to + * @self: the #NMDevice to add the pending action to * @action: a static string that identifies the action * @assert_not_yet_pending: if %TRUE, assert that the @action is currently not yet pending. * Otherwise, ignore duplicate scheduling of the same action silently. @@ -6305,9 +6989,9 @@ nm_device_supports_vlans (NMDevice *device) * a second time. */ gboolean -nm_device_add_pending_action (NMDevice *device, const char *action, gboolean assert_not_yet_pending) +nm_device_add_pending_action (NMDevice *self, const char *action, gboolean assert_not_yet_pending) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *iter; guint count = 0; @@ -6317,16 +7001,12 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass for (iter = priv->pending_actions; iter; iter = iter->next) { if (!strcmp (action, iter->data)) { if (assert_not_yet_pending) { - nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending", - nm_device_get_iface (device), - count + g_slist_length (iter), - action); + _LOGW (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending", + count + g_slist_length (iter), action); g_return_val_if_reached (FALSE); } else { - nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already pending (expected)", - nm_device_get_iface (device), - count + g_slist_length (iter), - action); + _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s' already pending (expected)", + count + g_slist_length (iter), action); } return FALSE; } @@ -6336,20 +7016,17 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action)); count++; - nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s'", - nm_device_get_iface (device), - count, - action); + _LOGD (LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); if (count == 1) - g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION); return TRUE; } /** * nm_device_remove_pending_action(): - * @device: the #NMDevice to remove the pending action from + * @self: the #NMDevice to remove the pending action from * @action: a static string that identifies the action * @assert_is_pending: if %TRUE, assert that the @action is pending. * If %FALSE, don't do anything if the current action is not pending and @@ -6360,9 +7037,9 @@ nm_device_add_pending_action (NMDevice *device, const char *action, gboolean ass * Returns: whether the @action was pending and is now removed. */ gboolean -nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending) +nm_device_remove_pending_action (NMDevice *self, const char *action, gboolean assert_is_pending) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); GSList *iter; guint count = 0; @@ -6370,64 +7047,73 @@ nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean for (iter = priv->pending_actions; iter; iter = iter->next) { if (!strcmp (action, iter->data)) { - nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s'", - nm_device_get_iface (device), - count + g_slist_length (iter->next), /* length excluding 'iter' */ - action); + _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s'", + count + g_slist_length (iter->next), /* length excluding 'iter' */ + action); g_free (iter->data); priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); if (priv->pending_actions == NULL) - g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + g_object_notify (G_OBJECT (self), NM_DEVICE_HAS_PENDING_ACTION); return TRUE; } count++; } if (assert_is_pending) { - nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending", - nm_device_get_iface (device), - count, - action); + _LOGW (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action); g_return_val_if_reached (FALSE); - } else { - nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' not pending (expected)", - nm_device_get_iface (device), - count, - action); - } + } else + _LOGD (LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending (expected)", count, action); + return FALSE; } gboolean -nm_device_has_pending_action (NMDevice *device) +nm_device_has_pending_action (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); return !!priv->pending_actions; } /***********************************************************/ +static void +_cleanup_ip_pre (NMDevice *self, gboolean deconfigure) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + priv->ip4_state = priv->ip6_state = IP_NONE; + nm_device_queued_ip_config_change_clear (self); + + dhcp4_cleanup (self, deconfigure, FALSE); + arp_cleanup (self); + dhcp6_cleanup (self, deconfigure, FALSE); + linklocal6_cleanup (self); + addrconf6_cleanup (self); + dnsmasq_cleanup (self); + aipd_cleanup (self); +} + static void _cleanup_generic_pre (NMDevice *self, gboolean deconfigure) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; /* Clean up when device was deactivated during call to firewall */ - if (priv->fw_manager) { - NMConnection *connection; - - if (priv->fw_call) { - nm_firewall_manager_cancel_call (priv->fw_manager, priv->fw_call); - priv->fw_call = NULL; - } + if (priv->fw_call) { + nm_firewall_manager_cancel_call (nm_firewall_manager_get (), priv->fw_call); + priv->fw_call = NULL; + } - connection = nm_device_get_connection (self); - if (deconfigure && connection) { - nm_firewall_manager_remove_from_zone (priv->fw_manager, - nm_device_get_ip_iface (self), - NULL); - } + connection = nm_device_get_connection (self); + if ( deconfigure + && connection + && !nm_device_uses_assumed_connection (self)) { + nm_firewall_manager_remove_from_zone (nm_firewall_manager_get (), + nm_device_get_ip_iface (self), + NULL); } ip_check_gw_ping_cleanup (self); @@ -6438,17 +7124,8 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure) /* Clear any queued transitions */ nm_device_queued_state_clear (self); - nm_device_queued_ip_config_change_clear (self); - - priv->ip4_state = priv->ip6_state = IP_NONE; - dhcp4_cleanup (self, deconfigure, FALSE); - arp_cleanup (self); - dhcp6_cleanup (self, deconfigure, FALSE); - linklocal6_cleanup (self); - addrconf6_cleanup (self); - dnsmasq_cleanup (self); - aipd_cleanup (self); + _cleanup_ip_pre (self, deconfigure); } static void @@ -6457,20 +7134,33 @@ _cleanup_generic_post (NMDevice *self, gboolean deconfigure) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE; + priv->default_route.v4_has = FALSE; + priv->default_route.v4_is_assumed = TRUE; + priv->default_route.v6_has = FALSE; + priv->default_route.v6_is_assumed = TRUE; + + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), self); + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), self); + /* Clean up IP configs; this does not actually deconfigure the * interface; the caller must flush routes and addresses explicitly. */ - nm_device_set_ip4_config (self, NULL, TRUE, &ignored); + nm_device_set_ip4_config (self, NULL, 0, TRUE, &ignored); nm_device_set_ip6_config (self, NULL, TRUE, &ignored); g_clear_object (&priv->dev_ip4_config); g_clear_object (&priv->ext_ip4_config); + g_clear_object (&priv->wwan_ip4_config); g_clear_object (&priv->vpn4_config); g_clear_object (&priv->ip4_config); g_clear_object (&priv->ac_ip6_config); g_clear_object (&priv->ext_ip6_config); g_clear_object (&priv->vpn6_config); + g_clear_object (&priv->wwan_ip6_config); g_clear_object (&priv->ip6_config); + priv->ext_ip4_config_had_any_addresses = FALSE; + priv->ext_ip6_config_had_any_addresses = FALSE; + clear_act_request (self); /* Clear legacy IPv4 address property */ @@ -6507,13 +7197,10 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) g_return_if_fail (NM_IS_DEVICE (self)); - if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) { - nm_log_info (LOGD_DEVICE, "(%s): preparing device", - nm_device_get_iface (self)); - } else { - nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason '%s') [%d]", - nm_device_get_iface (self), reason_to_string (reason), reason); - } + if (reason == NM_DEVICE_STATE_REASON_NOW_MANAGED) + _LOGI (LOGD_DEVICE, "preparing device"); + else + _LOGI (LOGD_DEVICE, "deactivating device (reason '%s') [%d]", reason_to_string (reason), reason); /* Save whether or not we tried IPv6 for later */ priv = NM_DEVICE_GET_PRIVATE (self); @@ -6521,7 +7208,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) _cleanup_generic_pre (self, TRUE); /* Turn off kernel IPv6 */ - nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); + set_disable_ipv6 (self, "1"); nm_device_ipv6_sysctl_set (self, "accept_ra", "0"); nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); @@ -6547,6 +7234,170 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason) _cleanup_generic_post (self, TRUE); } +static char * +bin2hexstr (const char *bytes, gsize len) +{ + GString *str; + int i; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + + str = g_string_sized_new (len * 2 + 1); + for (i = 0; i < len; i++) { + if (str->len) + g_string_append_c (str, ':'); + g_string_append_printf (str, "%02x", (guint8) bytes[i]); + } + return g_string_free (str, FALSE); +} + +static char * +find_dhcp4_address (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + guint i, n; + + if (!priv->ip4_config) + return NULL; + + n = nm_ip4_config_get_num_addresses (priv->ip4_config); + 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) + return g_strdup (nm_utils_inet4_ntop (a->address, NULL)); + } + return NULL; +} + +void +nm_device_spawn_iface_helper (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean configured = FALSE; + NMConnection *connection; + GError *error = NULL; + const char *method; + GPtrArray *argv; + gs_free char *dhcp4_address = NULL; + + if (priv->state != NM_DEVICE_STATE_ACTIVATED) + return; + if (!nm_device_can_assume_connections (self)) + return; + + connection = nm_device_get_connection (self); + g_assert (connection); + + argv = g_ptr_array_sized_new (10); + g_ptr_array_set_free_func (argv, g_free); + + g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/nm-iface-helper")); + g_ptr_array_add (argv, g_strdup ("--ifname")); + g_ptr_array_add (argv, g_strdup (nm_device_get_ip_iface (self))); + g_ptr_array_add (argv, g_strdup ("--uuid")); + g_ptr_array_add (argv, g_strdup (nm_connection_get_uuid (connection))); + + dhcp4_address = find_dhcp4_address (self); + + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + if ( priv->ip4_config + && priv->ip4_state == IP_DONE + && g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0 + && priv->dhcp4_client + && dhcp4_address) { + NMSettingIPConfig *s_ip4; + GBytes *client_id; + char *hex_client_id; + const char *hostname; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + + g_ptr_array_add (argv, g_strdup ("--priority4")); + g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip4_route_metric (self))); + + g_ptr_array_add (argv, g_strdup ("--dhcp4")); + g_ptr_array_add (argv, g_strdup (dhcp4_address)); + if (nm_setting_ip_config_get_may_fail (s_ip4) == FALSE) + g_ptr_array_add (argv, g_strdup ("--dhcp4-required")); + + 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), + g_bytes_get_size (client_id)); + g_ptr_array_add (argv, hex_client_id); + } + + hostname = nm_dhcp_client_get_hostname (priv->dhcp4_client); + if (client_id) { + g_ptr_array_add (argv, g_strdup ("--dhcp4-hostname")); + g_ptr_array_add (argv, g_strdup (hostname)); + } + + configured = TRUE; + } + + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if ( priv->ip6_config + && priv->ip6_state == IP_DONE + && g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + && priv->rdisc + && priv->ac_ip6_config) { + NMSettingIPConfig *s_ip6; + char *hex_iid; + NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + + g_ptr_array_add (argv, g_strdup ("--priority6")); + g_ptr_array_add (argv, g_strdup_printf ("%u", nm_device_get_ip6_route_metric (self))); + + g_ptr_array_add (argv, g_strdup ("--slaac")); + + if (nm_setting_ip_config_get_may_fail (s_ip6) == FALSE) + g_ptr_array_add (argv, g_strdup ("--slaac-required")); + + 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)) { + 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); + } + + configured = TRUE; + } + + if (configured) { + GPid pid; + + g_ptr_array_add (argv, NULL); + + if (nm_logging_enabled (LOGL_DEBUG, LOGD_DEVICE)) { + char *tmp; + + tmp = g_strjoinv (" ", (char **) argv->pdata); + _LOGD (LOGD_DEVICE, "running '%s'", tmp); + g_free (tmp); + } + + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) { + _LOGI (LOGD_DEVICE, "spawned helper PID %u", (guint) pid); + } else { + _LOGW (LOGD_DEVICE, "failed to spawn helper: %s", error->message); + g_error_free (error); + } + } + + g_ptr_array_unref (argv); +} + /***********************************************************/ static gboolean @@ -6558,22 +7409,33 @@ ip_config_valid (NMDeviceState state) } static void -notify_ip_properties (NMDevice *device) +notify_ip_properties (NMDevice *self) { - g_object_notify (G_OBJECT (device), NM_DEVICE_IP_IFACE); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP4_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP4_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_IP6_CONFIG); - g_object_notify (G_OBJECT (device), NM_DEVICE_DHCP6_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP_IFACE); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP4_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_IP6_CONFIG); + g_object_notify (G_OBJECT (self), NM_DEVICE_DHCP6_CONFIG); } static void -_set_state_full (NMDevice *device, +ip6_managed_setup (NMDevice *self) +{ + set_nm_ipv6ll (self, TRUE); + set_disable_ipv6 (self, "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); +} + +static void +_set_state_full (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, gboolean quitting) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceState old_state; NMActRequest *req; gboolean no_firmware = FALSE; @@ -6583,7 +7445,7 @@ _set_state_full (NMDevice *device, g_warn_if_fail (priv->in_state_changed == FALSE); priv->in_state_changed = TRUE; - g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_DEVICE (self)); /* Do nothing if state isn't changing, but as a special case allow * re-setting UNAVAILABLE if the device is missing firmware so that we @@ -6599,78 +7461,96 @@ _set_state_full (NMDevice *device, priv->state = state; priv->state_reason = reason; - nm_log_info (LOGD_DEVICE, "(%s): device state change: %s -> %s (reason '%s') [%d %d %d]", - nm_device_get_iface (device), - state_to_string (old_state), - state_to_string (state), - reason_to_string (reason), - old_state, - state, - reason); + _LOGI (LOGD_DEVICE, "device state change: %s -> %s (reason '%s') [%d %d %d]", + state_to_string (old_state), + state_to_string (state), + reason_to_string (reason), + old_state, + state, + reason); /* Clear any queued transitions */ - nm_device_queued_state_clear (device); + nm_device_queued_state_clear (self); - dispatcher_cleanup (device); + dispatcher_cleanup (self); /* Cache the activation request for the dispatcher */ req = priv->act_request ? g_object_ref (priv->act_request) : NULL; if (state <= NM_DEVICE_STATE_UNAVAILABLE) { - _clear_available_connections (device, TRUE); + _clear_available_connections (self, TRUE); g_clear_object (&priv->queued_act_request); } /* Update the available connections list when a device first becomes available */ - if ( state >= NM_DEVICE_STATE_DISCONNECTED - && old_state < NM_DEVICE_STATE_DISCONNECTED) - nm_device_recheck_available_connections (device); + if ( (state >= NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) + || nm_device_get_default_unmanaged (self)) + nm_device_recheck_available_connections (self); /* Handle the new state here; but anything that could trigger * another state change should be done below. */ switch (state) { case NM_DEVICE_STATE_UNMANAGED: - nm_device_set_firmware_missing (device, FALSE); + nm_device_set_firmware_missing (self, FALSE); if (old_state > NM_DEVICE_STATE_UNMANAGED) { /* Clean up if the device is now unmanaged but was activated */ - if (nm_device_get_act_request (device)) - nm_device_cleanup (device, reason); - nm_device_take_down (device, TRUE); - restore_ip6_properties (device); + if (nm_device_get_act_request (self)) + nm_device_cleanup (self, reason); + nm_device_take_down (self, TRUE); + set_nm_ipv6ll (self, FALSE); + restore_ip6_properties (self); } break; case NM_DEVICE_STATE_UNAVAILABLE: if (old_state == NM_DEVICE_STATE_UNMANAGED) { - save_ip6_properties (device); - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { - nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); - nm_device_ipv6_sysctl_set (device, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (device, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (device, "accept_ra_rtr_pref", "0"); - nm_device_ipv6_sysctl_set (device, "use_tempaddr", "0"); - } + save_ip6_properties (self); + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) + ip6_managed_setup (self); } - if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { - if (!nm_device_bring_up (device, TRUE, &no_firmware) && no_firmware) - nm_log_warn (LOGD_HW, "(%s): firmware may be missing.", nm_device_get_iface (device)); - nm_device_set_firmware_missing (device, no_firmware ? TRUE : FALSE); + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { + if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) + _LOGW (LOGD_HW, "firmware may be missing."); + nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); + } + + /* Ensure the device gets deactivated in response to stuff like + * carrier changes or rfkill. But don't deactivate devices that are + * about to assume a connection since that defeats the purpose of + * assuming the device's existing connection. + * + * Note that we "deactivate" the device even when coming from + * UNMANAGED, to ensure that it's in a clean state. + */ + nm_device_cleanup (self, reason); } - /* Ensure the device gets deactivated in response to stuff like - * carrier changes or rfkill. But don't deactivate devices that are - * about to assume a connection since that defeats the purpose of - * assuming the device's existing connection. - * - * Note that we "deactivate" the device even when coming from - * UNMANAGED, to ensure that it's in a clean state. - */ - if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) - nm_device_cleanup (device, reason); break; case NM_DEVICE_STATE_DISCONNECTED: - if (old_state > NM_DEVICE_STATE_UNAVAILABLE) - nm_device_cleanup (device, reason); + if (old_state > NM_DEVICE_STATE_DISCONNECTED) { + /* Ensure devices that previously assumed a connection now have + * userspace IPv6LL enabled. + */ + set_nm_ipv6ll (self, TRUE); + + nm_device_cleanup (self, reason); + } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) { + if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { + /* Ensure IPv6 is set up as it may not have been done when + * entering the UNAVAILABLE state depending on the reason. + */ + ip6_managed_setup (self); + } + } + break; + case NM_DEVICE_STATE_NEED_AUTH: + if (old_state > NM_DEVICE_STATE_NEED_AUTH) { + /* Clean up any half-done IP operations if the device's layer2 + * finds out it needs authentication during IP config. + */ + _cleanup_ip_pre (self, TRUE); + } break; default: break; @@ -6679,11 +7559,11 @@ _set_state_full (NMDevice *device, /* Reset autoconnect flag when the device is activating or connected. */ if ( state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) - priv->autoconnect = TRUE; + nm_device_set_autoconnect (self, TRUE); - g_object_notify (G_OBJECT (device), NM_DEVICE_STATE); - g_object_notify (G_OBJECT (device), NM_DEVICE_STATE_REASON); - g_signal_emit_by_name (device, "state-changed", state, old_state, reason); + g_object_notify (G_OBJECT (self), NM_DEVICE_STATE); + g_object_notify (G_OBJECT (self), NM_DEVICE_STATE_REASON); + g_signal_emit_by_name (self, "state-changed", state, old_state, reason); /* Post-process the event after internal notification */ @@ -6695,35 +7575,33 @@ _set_state_full (NMDevice *device, * we can't change states again from the state handler for a variety of * reasons. */ - if (nm_device_is_available (device)) { - nm_log_dbg (LOGD_DEVICE, "(%s): device is available, will transition to DISCONNECTED", - nm_device_get_iface (device)); - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + if (nm_device_is_available (self)) { + _LOGD (LOGD_DEVICE, "device is available, will transition to DISCONNECTED"); + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); } else { - if (old_state == NM_DEVICE_STATE_UNMANAGED) { - nm_log_dbg (LOGD_DEVICE, "(%s): device not yet available for transition to DISCONNECTED", - nm_device_get_iface (device)); - } else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE - && nm_device_get_default_unmanaged (device)) - nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); + if (old_state == NM_DEVICE_STATE_UNMANAGED) + _LOGD (LOGD_DEVICE, "device not yet available for transition to DISCONNECTED"); + else if ( old_state > NM_DEVICE_STATE_UNAVAILABLE + && nm_device_get_default_unmanaged (self)) + nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); } break; case NM_DEVICE_STATE_DEACTIVATING: if (quitting) { nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN, nm_act_request_get_connection (req), - device); + self); } else { priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; priv->dispatcher.post_state_reason = reason; if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN, nm_act_request_get_connection (req), - device, + self, dispatcher_complete_proceed_state, - device, + self, &priv->dispatcher.call_id)) { /* Just proceed on errors */ - dispatcher_complete_proceed_state (0, device); + dispatcher_complete_proceed_state (0, self); } } break; @@ -6733,26 +7611,32 @@ _set_state_full (NMDevice *device, queued_req = priv->queued_act_request; priv->queued_act_request = NULL; - _device_activate (device, queued_req); + _device_activate (self, queued_req); g_object_unref (queued_req); } else if ( old_state > NM_DEVICE_STATE_DISCONNECTED - && nm_device_get_default_unmanaged (device)) - nm_device_queue_state (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); + && nm_device_get_default_unmanaged (self)) + nm_device_queue_state (self, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NONE); break; case NM_DEVICE_STATE_ACTIVATED: - nm_log_info (LOGD_DEVICE, "Activation (%s) successful, device activated.", - nm_device_get_iface (device)); - nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), device, NULL, NULL, NULL); + _LOGI (LOGD_DEVICE, "Activation: successful, device activated."); + nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL); break; case NM_DEVICE_STATE_FAILED: - connection = nm_device_get_connection (device); - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s) failed for connection '%s'", - nm_device_get_iface (device), - connection ? nm_connection_get_id (connection) : ""); + if (nm_device_uses_assumed_connection (self)) { + /* Avoid tearing down assumed connection, assume it's connected */ + nm_device_queue_state (self, + NM_DEVICE_STATE_ACTIVATED, + NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); + break; + } + + connection = nm_device_get_connection (self); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: failed for connection '%s'", + connection ? nm_connection_get_id (connection) : ""); /* Notify any slaves of the unexpected failure */ - nm_device_master_release_slaves (device); + nm_device_master_release_slaves (self); /* If the connection doesn't yet have a timestamp, set it to zero so that * we can distinguish between connections we've tried to activate and have @@ -6769,41 +7653,40 @@ _set_state_full (NMDevice *device, * immediately because we can't change states again from the state * handler for a variety of reasons. */ - nm_device_queue_state (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); + nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE); break; case NM_DEVICE_STATE_IP_CHECK: - nm_device_start_ip_check (device); + nm_device_start_ip_check (self); /* IP-related properties are only valid when the device has IP configuration; * now that it does, ensure their change notifications are emitted. */ - notify_ip_properties (device); + notify_ip_properties (self); break; case NM_DEVICE_STATE_SECONDARIES: - ip_check_gw_ping_cleanup (device); - nm_log_dbg (LOGD_DEVICE, "(%s): device entered SECONDARIES state", - nm_device_get_iface (device)); + ip_check_gw_ping_cleanup (self); + _LOGD (LOGD_DEVICE, "device entered SECONDARIES state"); break; default: break; } if (state > NM_DEVICE_STATE_DISCONNECTED) - delete_on_deactivate_unschedule (device); + delete_on_deactivate_unschedule (self); if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING) && (state != NM_DEVICE_STATE_DEACTIVATING)) { if (quitting) - nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device); + nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self); else - nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self, NULL, NULL, NULL); } /* IP-related properties are only valid when the device has IP configuration. * If it no longer does, ensure their change notifications are emitted. */ if (ip_config_valid (old_state) && !ip_config_valid (state)) - notify_ip_properties (device); + notify_ip_properties (self); /* Dispose of the cached activation request */ if (req) @@ -6813,11 +7696,11 @@ _set_state_full (NMDevice *device, } void -nm_device_state_changed (NMDevice *device, +nm_device_state_changed (NMDevice *self, NMDeviceState state, NMDeviceStateReason reason) { - _set_state_full (device, state, reason, FALSE); + _set_state_full (self, state, reason, FALSE); } static gboolean @@ -6829,10 +7712,9 @@ queued_set_state (gpointer user_data) NMDeviceStateReason new_reason; if (priv->queued_state.id) { - nm_log_dbg (LOGD_DEVICE, "(%s): running queued state change to %s (id %d)", - nm_device_get_iface (self), - state_to_string (priv->queued_state.state), - priv->queued_state.id); + _LOGD (LOGD_DEVICE, "running queued state change to %s (id %d)", + state_to_string (priv->queued_state.state), + priv->queued_state.id); /* Clear queued state struct before triggering state change, since * the state change may queue another state. @@ -6871,10 +7753,9 @@ nm_device_queue_state (NMDevice *self, /* We should only ever have one delayed state transition at a time */ if (priv->queued_state.id) { - nm_log_warn (LOGD_DEVICE, "(%s): overwriting previously queued state change to %s (%s)", - nm_device_get_iface (self), - state_to_string (priv->queued_state.state), - reason_to_string (priv->queued_state.reason)); + _LOGW (LOGD_DEVICE, "overwriting previously queued state change to %s (%s)", + state_to_string (priv->queued_state.state), + reason_to_string (priv->queued_state.reason)); nm_device_queued_state_clear (self); } @@ -6882,9 +7763,9 @@ nm_device_queue_state (NMDevice *self, priv->queued_state.reason = reason; priv->queued_state.id = g_idle_add (queued_set_state, self); - nm_log_dbg (LOGD_DEVICE, "(%s): queued state change to %s due to %s (id %d)", - nm_device_get_iface (self), state_to_string (state), reason_to_string (reason), - priv->queued_state.id); + _LOGD (LOGD_DEVICE, "queued state change to %s due to %s (id %d)", + state_to_string (state), reason_to_string (reason), + priv->queued_state.id); } NMDeviceState @@ -6905,8 +7786,8 @@ nm_device_queued_state_clear (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if (priv->queued_state.id) { - nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued state transition (id %d)", - nm_device_get_iface (self), priv->queued_state.id); + _LOGD (LOGD_DEVICE, "clearing queued state transition (id %d)", + priv->queued_state.id); g_source_remove (priv->queued_state.id); nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state), TRUE); } @@ -6914,152 +7795,112 @@ nm_device_queued_state_clear (NMDevice *self) } NMDeviceState -nm_device_get_state (NMDevice *device) +nm_device_get_state (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); + g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_STATE_UNKNOWN); - return NM_DEVICE_GET_PRIVATE (device)->state; + return NM_DEVICE_GET_PRIVATE (self)->state; } /***********************************************************/ /* NMConfigDevice interface related stuff */ -static guint -nm_device_get_hw_address_length (NMDevice *dev, gboolean *out_permanent) -{ - return NM_DEVICE_GET_CLASS (dev)->get_hw_address_length (dev, out_permanent); -} - -const guint8 * -nm_device_get_hw_address (NMDevice *dev, guint *out_len) +const char * +nm_device_get_hw_address (NMDevice *self) { NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (dev), NULL); - priv = NM_DEVICE_GET_PRIVATE (dev); - - if (out_len) - *out_len = priv->hw_addr_len; + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->hw_addr_len == 0) - return NULL; - else - return priv->hw_addr; + return priv->hw_addr_len ? priv->hw_addr : NULL; } -gboolean -nm_device_update_hw_address (NMDevice *dev) +static void +nm_device_update_hw_address (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); - gboolean changed = FALSE, permanent = FALSE; - - priv->hw_addr_len = nm_device_get_hw_address_length (dev, &permanent); - - /* If the address can't be changed, don't bother trying */ - if (permanent) - return FALSE; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int ifindex = nm_device_get_ifindex (self); + const guint8 *hwaddr; + gsize hwaddrlen = 0; - if (priv->hw_addr_len) { - int ifindex = nm_device_get_ip_ifindex (dev); - gsize addrlen; - const guint8 *binaddr; + if (ifindex <= 0) + return; - g_return_val_if_fail (ifindex > 0, FALSE); + hwaddr = nm_platform_link_get_address (ifindex, &hwaddrlen); - binaddr = nm_platform_link_get_address (ifindex, &addrlen); + if (hwaddrlen) { + if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) { + g_free (priv->hw_addr); + priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - if (addrlen != priv->hw_addr_len) { - nm_log_err (LOGD_HW | LOGD_DEVICE, - "(%s): hardware address is wrong length (got %zd, expected %d)", - nm_device_get_iface (dev), addrlen, priv->hw_addr_len); - } else { - changed = !!memcmp (priv->hw_addr, binaddr, addrlen); - if (changed) { - char *addrstr = nm_utils_hwaddr_ntoa_len (binaddr, priv->hw_addr_len); - - memcpy (priv->hw_addr, binaddr, addrlen); - nm_log_dbg (LOGD_HW | LOGD_DEVICE, - "(%s): hardware address is %s", - nm_device_get_iface (dev), addrstr); - g_free (addrstr); - g_object_notify (G_OBJECT (dev), NM_DEVICE_HW_ADDRESS); - } + _LOGD (LOGD_HW | LOGD_DEVICE, "hardware address now %s", priv->hw_addr); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); } } else { - int i; - - /* hw_addr_len is now 0; see if hw_addr was already empty */ - for (i = 0; i < sizeof (priv->hw_addr) && !changed; i++) { - if (priv->hw_addr[i]) - changed = TRUE; - } - if (changed) { - memset (priv->hw_addr, 0, sizeof (priv->hw_addr)); - nm_log_dbg (LOGD_HW | LOGD_DEVICE, - "(%s): previous hardware address is no longer valid", - nm_device_get_iface (dev)); - g_object_notify (G_OBJECT (dev), NM_DEVICE_HW_ADDRESS); + /* Invalid or no hardware address */ + if (priv->hw_addr_len != 0) { + g_clear_pointer (&priv->hw_addr, g_free); + _LOGD (LOGD_HW | LOGD_DEVICE, + "previous hardware address is no longer valid"); + g_object_notify (G_OBJECT (self), NM_DEVICE_HW_ADDRESS); } } - - return changed; + priv->hw_addr_len = hwaddrlen; } gboolean -nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, +nm_device_set_hw_addr (NMDevice *self, const char *addr, const char *detail, guint64 hw_log_domain) { - const char *iface; - char *mac_str = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean success = FALSE; - guint len; - const guint8 *cur_addr = nm_device_get_hw_address (device, &len); + const char *cur_addr = nm_device_get_hw_address (self); + guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; g_return_val_if_fail (addr != NULL, FALSE); - iface = nm_device_get_iface (device); - /* Do nothing if current MAC is same */ - if (cur_addr && !memcmp (cur_addr, addr, len)) { - nm_log_dbg (LOGD_DEVICE | hw_log_domain, "(%s): no MAC address change needed", iface); + if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { + _LOGD (LOGD_DEVICE | hw_log_domain, "no MAC address change needed"); return TRUE; } - - mac_str = nm_utils_hwaddr_ntoa_len (addr, len); + if (!nm_utils_hwaddr_aton (addr, addr_bytes, priv->hw_addr_len)) { + _LOGW (LOGD_DEVICE | hw_log_domain, "invalid MAC address %s", addr); + return FALSE; + } /* Can't change MAC address while device is up */ - nm_device_take_down (device, FALSE); + nm_device_take_down (self, FALSE); - success = nm_platform_link_set_address (nm_device_get_ip_ifindex (device), addr, len); + success = nm_platform_link_set_address (nm_device_get_ip_ifindex (self), addr_bytes, priv->hw_addr_len); if (success) { /* MAC address succesfully changed; update the current MAC to match */ - nm_device_update_hw_address (device); - cur_addr = nm_device_get_hw_address (device, NULL); - if (memcmp (cur_addr, addr, len) == 0) { - nm_log_info (LOGD_DEVICE | hw_log_domain, "(%s): %s MAC address to %s", - iface, detail, mac_str); + nm_device_update_hw_address (self); + cur_addr = nm_device_get_hw_address (self); + if (cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1)) { + _LOGI (LOGD_DEVICE | hw_log_domain, "%s MAC address to %s", + detail, addr); } else { - nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): new MAC address %s " - "not successfully set", - iface, mac_str); + _LOGW (LOGD_DEVICE | hw_log_domain, + "new MAC address %s not successfully set", addr); success = FALSE; } } else { - nm_log_warn (LOGD_DEVICE | hw_log_domain, "(%s): failed to %s MAC address to %s", - iface, detail, mac_str); + _LOGW (LOGD_DEVICE | hw_log_domain, "failed to %s MAC address to %s", + detail, addr); } - nm_device_bring_up (device, TRUE, NULL); - g_free (mac_str); + nm_device_bring_up (self, TRUE, NULL); return success; } /** * nm_device_spec_match_list: - * @device: an #NMDevice + * @self: an #NMDevice * @specs: (element-type utf8): a list of device specs * - * Checks if @device matches any of the specifications in @specs. The + * Checks if @self matches any of the specifications in @specs. The * currently-supported spec types are: * * "mac:00:11:22:33:44:55" - matches a device with the given @@ -7073,52 +7914,37 @@ nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, * * "*" - matches any device * - * Returns: #TRUE if @device matches one of the specs in @specs + * Returns: #TRUE if @self matches one of the specs in @specs */ gboolean -nm_device_spec_match_list (NMDevice *device, const GSList *specs) +nm_device_spec_match_list (NMDevice *self, const GSList *specs) { - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); if (!specs) return FALSE; - return NM_DEVICE_GET_CLASS (device)->spec_match_list (device, specs); + return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs); } static gboolean -spec_match_list (NMDevice *device, const GSList *specs) +spec_match_list (NMDevice *self, const GSList *specs) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - char *hwaddr_str; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean matched = FALSE; if (nm_match_spec_string (specs, "*")) return TRUE; - if (priv->hw_addr_len) { - hwaddr_str = nm_utils_hwaddr_ntoa_len (priv->hw_addr, priv->hw_addr_len); - matched = nm_match_spec_hwaddr (specs, hwaddr_str); - g_free (hwaddr_str); - } + if (priv->hw_addr_len) + matched = nm_match_spec_hwaddr (specs, priv->hw_addr); if (!matched) - matched = nm_match_spec_interface_name (specs, nm_device_get_iface (device)); + matched = nm_match_spec_interface_name (specs, nm_device_get_iface (self)); return matched; } -static guint -get_hw_address_length (NMDevice *dev, gboolean *out_permanent) -{ - size_t len; - - if (nm_platform_link_get_address (nm_device_get_ip_ifindex (dev), &len)) - return len; - else - return 0; -} - /***********************************************************/ #define DEFAULT_AUTOCONNECT TRUE @@ -7138,13 +7964,9 @@ nm_device_init (NMDevice *self) priv->unmanaged_flags = NM_UNMANAGED_INTERNAL; priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); -} -static void -nm_device_config_device_interface_init (NMConfigDeviceInterface *iface) -{ - iface->spec_match_list = (gboolean (*) (NMConfigDevice *, const GSList *)) nm_device_spec_match_list; - iface->get_hw_address = (const guint8 * (*) (NMConfigDevice *, guint *)) nm_device_get_hw_address; + priv->default_route.v4_is_assumed = TRUE; + priv->default_route.v6_is_assumed = TRUE; } /* @@ -7152,7 +7974,7 @@ nm_device_config_device_interface_init (NMConfigDeviceInterface *iface) * Returns driver and firmware versions to 'driver_version and' 'firmware_version' */ static gboolean -device_get_driver_info (const char *iface, char **driver_version, char **firmware_version) +device_get_driver_info (NMDevice *self, const char *iface, char **driver_version, char **firmware_version) { struct ethtool_drvinfo drvinfo; struct ifreq req; @@ -7160,7 +7982,7 @@ device_get_driver_info (const char *iface, char **driver_version, char **firmwar fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); + _LOGW (LOGD_HW, "couldn't open control socket."); return FALSE; } @@ -7173,8 +7995,8 @@ device_get_driver_info (const char *iface, char **driver_version, char **firmwar errno = 0; if (ioctl (fd, SIOCETHTOOL, &req) < 0) { - nm_log_dbg (LOGD_HW, "SIOCETHTOOL ioctl() failed: cmd=ETHTOOL_GDRVINFO, iface=%s, errno=%d", - iface, errno); + _LOGD (LOGD_HW, "SIOCETHTOOL ioctl() failed: cmd=ETHTOOL_GDRVINFO, iface=%s, errno=%d", + iface, errno); close (fd); return FALSE; } @@ -7193,7 +8015,7 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; - NMDevice *dev; + NMDevice *self; NMDevicePrivate *priv; NMPlatform *platform; static guint32 id = 0; @@ -7204,11 +8026,13 @@ constructor (GType type, if (!object) return NULL; - dev = NM_DEVICE (object); - priv = NM_DEVICE_GET_PRIVATE (dev); + self = NM_DEVICE (object); + priv = NM_DEVICE_GET_PRIVATE (self); + + _LOGD (LOGD_DEVICE, "constructor(): %s, kernel ifindex %d", G_OBJECT_TYPE_NAME (self), priv->ifindex); if (!priv->iface) { - nm_log_err (LOGD_DEVICE, "No device interface provided, ignoring"); + _LOGE (LOGD_DEVICE, "No device interface provided, ignoring"); goto error; } @@ -7217,52 +8041,60 @@ constructor (GType type, priv->udi = g_strdup_printf ("/virtual/device/placeholder/%d", id++); } - if (NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities) - priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); + if (NM_DEVICE_GET_CLASS (self)->get_generic_capabilities) + priv->capabilities |= NM_DEVICE_GET_CLASS (self)->get_generic_capabilities (self); - priv->fw_manager = nm_firewall_manager_get (); + if (priv->ifindex <= 0 && !device_has_capability (self, NM_DEVICE_CAP_IS_NON_KERNEL)) + _LOGW (LOGD_HW, "failed to look up interface index"); - device_get_driver_info (priv->iface, &priv->driver_version, &priv->firmware_version); + device_get_driver_info (self, priv->iface, &priv->driver_version, &priv->firmware_version); /* Watch for external IP config changes */ platform = nm_platform_get (); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), dev); - g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), dev); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (device_ip_changed), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (link_changed_cb), self); + + if (nm_platform_check_support_user_ipv6ll ()) { + int ip_ifindex = nm_device_get_ip_ifindex (self); + + if (ip_ifindex > 0) + priv->nm_ipv6ll = nm_platform_link_get_user_ipv6ll_enabled (ip_ifindex); + } return object; error: - g_object_unref (dev); + g_object_unref (self); return NULL; } static void constructed (GObject *object) { - NMDevice *dev = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (dev); + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + int master; - nm_device_update_hw_address (dev); + nm_device_update_hw_address (self); - if (NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_permanent_hw_address (dev); + if (NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address) + NM_DEVICE_GET_CLASS (self)->update_permanent_hw_address (self); - if (NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address) - NM_DEVICE_GET_CLASS (dev)->update_initial_hw_address (dev); + if (NM_DEVICE_GET_CLASS (self)->update_initial_hw_address) + NM_DEVICE_GET_CLASS (self)->update_initial_hw_address (self); /* Have to call update_initial_hw_address() before calling get_ignore_carrier() */ - if (device_has_capability (dev, NM_DEVICE_CAP_CARRIER_DETECT)) { - priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), NM_CONFIG_DEVICE (dev)); - - check_carrier (dev); - nm_log_info (LOGD_HW, - "(%s): carrier is %s%s", - nm_device_get_iface (NM_DEVICE (dev)), - priv->carrier ? "ON" : "OFF", - priv->ignore_carrier ? " (but ignored)" : ""); + if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { + priv->ignore_carrier = nm_config_get_ignore_carrier (nm_config_get (), self); + + check_carrier (self); + _LOGI (LOGD_HW, + "carrier is %s%s", + priv->carrier ? "ON" : "OFF", + priv->ignore_carrier ? " (but ignored)" : ""); } else { /* Fake online link when carrier detection is not available. */ priv->carrier = TRUE; @@ -7271,27 +8103,42 @@ constructed (GObject *object) if (priv->ifindex > 0) { priv->is_software = nm_platform_link_is_software (priv->ifindex); priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex); + priv->mtu = nm_platform_link_get_mtu (priv->ifindex); } + /* Indicate software device in capabilities. */ + if (priv->is_software) + priv->capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; - if (priv->ifindex > 0) - priv->mtu = nm_platform_link_get_mtu (priv->ifindex); + /* Enslave ourselves */ + master = nm_platform_link_get_master (priv->ifindex); + if (master) + device_set_master (self, master); 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), - dev); + self); g_signal_connect (priv->con_provider, NM_CP_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (cp_connection_removed), - dev); + self); g_signal_connect (priv->con_provider, NM_CP_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (cp_connection_updated), - dev); + self); + + /* Update default-unmanaged device available connections immediately, + * since they don't transition from UNMANAGED (and thus the state handler + * doesn't run and update them) until something external happens. + */ + if (nm_device_get_default_unmanaged (self)) { + nm_device_set_autoconnect (self, FALSE); + nm_device_recheck_available_connections (self); + } G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); } @@ -7303,6 +8150,8 @@ dispose (GObject *object) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatform *platform; + _LOGD (LOGD_DEVICE, "dispose(): %s", G_OBJECT_TYPE_NAME (self)); + dispatcher_cleanup (self); _cleanup_generic_pre (self, FALSE); @@ -7310,6 +8159,9 @@ dispose (GObject *object) g_warn_if_fail (priv->slaves == NULL); g_assert (priv->master_ready_id == 0); + /* Let the kernel manage IPv6LL again */ + set_nm_ipv6ll (self, FALSE); + _cleanup_generic_post (self, FALSE); g_clear_pointer (&priv->ip6_saved_properties, g_hash_table_unref); @@ -7342,8 +8194,6 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self); g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (link_changed_cb), self); - g_clear_object (&priv->fw_manager); - G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); } @@ -7353,6 +8203,9 @@ finalize (GObject *object) NMDevice *self = NM_DEVICE (object); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + _LOGD (LOGD_DEVICE, "finalize(): %s", G_OBJECT_TYPE_NAME (self)); + + g_free (priv->hw_addr); g_slist_free_full (priv->pending_actions, g_free); g_clear_pointer (&priv->physical_port_id, g_free); g_free (priv->udi); @@ -7363,8 +8216,7 @@ finalize (GObject *object) g_free (priv->driver_version); g_free (priv->firmware_version); g_free (priv->type_desc); - if (priv->dhcp_anycast_address) - g_byte_array_free (priv->dhcp_anycast_address, TRUE); + g_free (priv->dhcp_anycast_address); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); } @@ -7373,9 +8225,11 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + NMDevice *self = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMPlatformLink *platform_device; - const char *hw_addr; + const char *hw_addr, *p; + guint count; switch (prop_id) { case PROP_PLATFORM_DEVICE: @@ -7386,6 +8240,7 @@ set_property (GObject *object, guint prop_id, g_free (priv->iface); priv->iface = g_strdup (platform_device->name); priv->ifindex = platform_device->ifindex; + priv->up = platform_device->up; g_free (priv->driver); priv->driver = g_strdup (platform_device->driver); } @@ -7399,18 +8254,10 @@ set_property (GObject *object, guint prop_id, case PROP_IFACE: if (g_value_get_string (value)) { g_free (priv->iface); - priv->ifindex = 0; priv->iface = g_value_dup_string (value); - - /* Only look up the ifindex if it appears to be an actual kernel - * interface name. eg Bluetooth devices won't have one until we know - * the IP interface. - */ - if (priv->iface && !strchr (priv->iface, ':')) { - priv->ifindex = nm_platform_link_get_ifindex (priv->iface); - if (priv->ifindex <= 0) - nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", priv->iface); - } + priv->ifindex = nm_platform_link_get_ifindex (priv->iface); + if (priv->ifindex > 0) + priv->up = nm_platform_link_is_up (priv->ifindex); } break; case PROP_DRIVER: @@ -7434,7 +8281,7 @@ set_property (GObject *object, guint prop_id, priv->ip4_address = g_value_get_uint (value); break; case PROP_AUTOCONNECT: - priv->autoconnect = g_value_get_boolean (value); + nm_device_set_autoconnect (self, g_value_get_boolean (value)); break; case PROP_FIRMWARE_MISSING: priv->firmware_missing = g_value_get_boolean (value); @@ -7454,19 +8301,30 @@ set_property (GObject *object, guint prop_id, priv->is_master = g_value_get_boolean (value); break; case PROP_HW_ADDRESS: - priv->hw_addr_len = nm_device_get_hw_address_length (NM_DEVICE (object), NULL); - - hw_addr = g_value_get_string (value); - if (!hw_addr) - break; - if (priv->hw_addr_len == 0) { - g_warn_if_fail (*hw_addr == '\0'); + /* construct only */ + p = hw_addr = g_value_get_string (value); + + /* Hardware address length is the number of ':' plus 1 */ + count = 1; + while (p && *p) { + if (*p++ == ':') + count++; + } + if (count < ETH_ALEN || count > NM_UTILS_HWADDR_LEN_MAX) { + if (hw_addr && *hw_addr) { + _LOGW (LOGD_DEVICE, "ignoring hardware address '%s' with unexpected length %d", + hw_addr, count); + } break; } - if (!nm_utils_hwaddr_aton_len (hw_addr, priv->hw_addr, priv->hw_addr_len)) { - g_warning ("Could not parse hw-address '%s'", hw_addr); - memset (priv->hw_addr, 0, sizeof (priv->hw_addr)); + priv->hw_addr_len = count; + g_free (priv->hw_addr); + if (nm_utils_hwaddr_valid (hw_addr, priv->hw_addr_len)) + priv->hw_addr = g_strdup (hw_addr); + else { + _LOGW (LOGD_DEVICE, "could not parse hw-address '%s'", hw_addr); + priv->hw_addr = NULL; } break; default: @@ -7596,10 +8454,7 @@ get_property (GObject *object, guint prop_id, g_value_set_object (value, priv->master); break; case PROP_HW_ADDRESS: - if (priv->hw_addr_len) - g_value_take_string (value, nm_utils_hwaddr_ntoa_len (priv->hw_addr, priv->hw_addr_len)); - else - g_value_set_string (value, NULL); + g_value_set_string (value, priv->hw_addr); break; case PROP_HAS_PENDING_ACTION: g_value_set_boolean (value, nm_device_has_pending_action (self)); @@ -7644,257 +8499,226 @@ nm_device_class_init (NMDeviceClass *klass) klass->bring_up = bring_up; klass->take_down = take_down; klass->carrier_changed = carrier_changed; - klass->get_hw_address_length = get_hw_address_length; + klass->get_ip_iface_identifier = get_ip_iface_identifier; /* Properties */ g_object_class_install_property (object_class, PROP_PLATFORM_DEVICE, - g_param_spec_pointer (NM_DEVICE_PLATFORM_DEVICE, - "Platform Device", - "NMPlatform device object", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_pointer (NM_DEVICE_PLATFORM_DEVICE, "", "", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_UDI, - g_param_spec_string (NM_DEVICE_UDI, - "UDI", - "Unique Device Identifier", + g_param_spec_string (NM_DEVICE_UDI, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IFACE, - g_param_spec_string (NM_DEVICE_IFACE, - "Interface", - "Interface", + g_param_spec_string (NM_DEVICE_IFACE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_IFACE, - g_param_spec_string (NM_DEVICE_IP_IFACE, - "IP Interface", - "IP Interface", + g_param_spec_string (NM_DEVICE_IP_IFACE, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_DEVICE_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_DEVICE_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER_VERSION, - g_param_spec_string (NM_DEVICE_DRIVER_VERSION, - "Driver Version", - "Driver Version", + g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FIRMWARE_VERSION, - g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, - "Firmware Version", - "Firmware Version", + g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_CAPABILITIES, - "Capabilities", - "Capabilities", + g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "", 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CARRIER, - g_param_spec_boolean (NM_DEVICE_CARRIER, - "Carrier", - "Carrier", + g_param_spec_boolean (NM_DEVICE_CARRIER, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MTU, - g_param_spec_uint (NM_DEVICE_MTU, - "MTU", - "MTU", + g_param_spec_uint (NM_DEVICE_MTU, "", "", 0, G_MAXUINT32, 1500, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP4_ADDRESS, - g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, - "IP4 address", - "IP4 address", + g_param_spec_uint (NM_DEVICE_IP4_ADDRESS, "", "", 0, G_MAXUINT32, 0, /* FIXME */ - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP4_CONFIG, - g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, - "IP4 Config", - "IP4 Config", + g_param_spec_boxed (NM_DEVICE_IP4_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DHCP4_CONFIG, - g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", + g_param_spec_boxed (NM_DEVICE_DHCP4_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP6_CONFIG, - g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, - "IP6 Config", - "IP6 Config", + g_param_spec_boxed (NM_DEVICE_IP6_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DHCP6_CONFIG, - g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", + g_param_spec_boxed (NM_DEVICE_DHCP6_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_DEVICE_STATE, - "State", - "State", + g_param_spec_uint (NM_DEVICE_STATE, "", "", 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE_REASON, - g_param_spec_boxed (NM_DEVICE_STATE_REASON, - "StateReason", - "StateReason", + g_param_spec_boxed (NM_DEVICE_STATE_REASON, "", "", DBUS_TYPE_STATE_REASON_STRUCT, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTION, - g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, - "ActiveConnection", - "ActiveConnection", + g_param_spec_boxed (NM_DEVICE_ACTIVE_CONNECTION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_TYPE, - g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, - "DeviceType", - "DeviceType", + g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "", 0, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MANAGED, - g_param_spec_boolean (NM_DEVICE_MANAGED, - "Managed", - "Managed", + g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AUTOCONNECT, - g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, - "Autoconnect", - "Autoconnect", + g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", DEFAULT_AUTOCONNECT, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FIRMWARE_MISSING, - g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, - "FirmwareMissing", - "Firmware missing", + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TYPE_DESC, - g_param_spec_string (NM_DEVICE_TYPE_DESC, - "Type Description", - "Device type description", + g_param_spec_string (NM_DEVICE_TYPE_DESC, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RFKILL_TYPE, - g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, - "Rfkill Type", - "Type of rfkill switch (if any) supported by this device", + g_param_spec_uint (NM_DEVICE_RFKILL_TYPE, "", "", RFKILL_TYPE_WLAN, RFKILL_TYPE_MAX, RFKILL_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IFINDEX, - g_param_spec_int (NM_DEVICE_IFINDEX, - "Ifindex", - "Ifindex", + g_param_spec_int (NM_DEVICE_IFINDEX, "", "", 0, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_AVAILABLE_CONNECTIONS, - g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, - "AvailableConnections", - "AvailableConnections", + g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PHYSICAL_PORT_ID, - g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, - "PhysicalPortId", - "PhysicalPortId", + g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IS_MASTER, - g_param_spec_boolean (NM_DEVICE_IS_MASTER, - "IsMaster", - "IsMaster", + g_param_spec_boolean (NM_DEVICE_IS_MASTER, "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MASTER, - g_param_spec_object (NM_DEVICE_MASTER, - "Master", - "Master", + g_param_spec_object (NM_DEVICE_MASTER, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_HW_ADDRESS, - "Hardware Address", - "Hardware address", + g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HAS_PENDING_ACTION, - g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, - "Has pending action", - "Has pending action", + g_param_spec_boolean (NM_DEVICE_HAS_PENDING_ACTION, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[STATE_CHANGED] = diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index f74486e6..b3855c74 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -19,24 +19,18 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_H -#define NM_DEVICE_H +#ifndef __NETWORKMANAGER_DEVICE_H__ +#define __NETWORKMANAGER_DEVICE_H__ #include #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-types.h" -#include "nm-activation-request.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" -#include "nm-dhcp4-config.h" -#include "nm-dhcp6-config.h" #include "nm-connection.h" #include "nm-rfkill-manager.h" -#include "nm-connection-provider.h" -#include "nm-platform.h" +#include "NetworkManagerUtils.h" /* Properties */ #define NM_DEVICE_UDI "udi" @@ -62,12 +56,13 @@ #define NM_DEVICE_AVAILABLE_CONNECTIONS "available-connections" #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_MTU "mtu" -#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ -#define NM_DEVICE_IS_MASTER "is-master" /* Internal only */ -#define NM_DEVICE_MASTER "master" /* Internal only */ -#define NM_DEVICE_HW_ADDRESS "hw-address" /* Internal only */ +#define NM_DEVICE_HW_ADDRESS "hw-address" + +#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ +#define NM_DEVICE_IS_MASTER "is-master" /* Internal only */ +#define NM_DEVICE_MASTER "master" /* Internal only */ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ @@ -90,12 +85,6 @@ G_BEGIN_DECLS typedef enum NMActStageReturn NMActStageReturn; -typedef enum { - NM_DEVICE_ERROR_CONNECTION_ACTIVATING = 0, /*< nick=ConnectionActivating >*/ - NM_DEVICE_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_DEVICE_ERROR_NOT_ACTIVE, /*< nick=NotActive >*/ -} NMDeviceError; - struct _NMDevice { GObject parent; }; @@ -120,10 +109,10 @@ typedef struct { /* Carrier state (IFF_LOWER_UP) */ void (*carrier_changed) (NMDevice *, gboolean carrier); - void (* update_hw_address) (NMDevice *self); void (* update_permanent_hw_address) (NMDevice *self); void (* update_initial_hw_address) (NMDevice *self); - guint (* get_hw_address_length) (NMDevice *self, gboolean *out_permanent); + + gboolean (* get_ip_iface_identifier) (NMDevice *self, NMUtilsIPv6IfaceId *out_iid); guint32 (* get_generic_capabilities) (NMDevice *self); @@ -183,7 +172,7 @@ typedef struct { /* Called right before IP config is set; use for setting MTU etc */ void (* ip4_config_pre_commit) (NMDevice *self, NMIP4Config *config); - void (* ip6_config_pre_commit) (NMDevice *self); + void (* ip6_config_pre_commit) (NMDevice *self, NMIP6Config *config); void (* deactivate) (NMDevice *self); @@ -192,6 +181,11 @@ typedef struct { /* Update the connection with currently configured L2 settings */ void (* update_connection) (NMDevice *device, NMConnection *connection); + gboolean (*master_update_slave_connection) (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error); + gboolean (* enslave_slave) (NMDevice *self, NMDevice *slave, NMConnection *connection, @@ -207,6 +201,8 @@ typedef struct { gboolean (* component_added) (NMDevice *self, GObject *component); gboolean (* owns_iface) (NMDevice *self, const char *iface); + + NMConnection * (* new_default_connection) (NMDevice *self); } NMDeviceClass; @@ -220,6 +216,8 @@ GType nm_device_get_type (void); const char * nm_device_get_path (NMDevice *dev); void nm_device_dbus_export (NMDevice *device); +void nm_device_finish_init (NMDevice *device); + const char * nm_device_get_udi (NMDevice *dev); const char * nm_device_get_iface (NMDevice *dev); int nm_device_get_ifindex (NMDevice *dev); @@ -232,11 +230,13 @@ const char * nm_device_get_type_desc (NMDevice *dev); NMDeviceType nm_device_get_device_type (NMDevice *dev); int nm_device_get_priority (NMDevice *dev); +guint32 nm_device_get_ip4_route_metric (NMDevice *dev); +guint32 nm_device_get_ip6_route_metric (NMDevice *dev); -const guint8 * nm_device_get_hw_address (NMDevice *dev, guint *out_len); +const char * nm_device_get_hw_address (NMDevice *dev); -NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *dev); -NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *dev); +NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); +NMDhcp6Config * nm_device_get_dhcp6_config (NMDevice *dev); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); void nm_device_set_vpn4_config (NMDevice *dev, NMIP4Config *config); @@ -255,14 +255,21 @@ NMDevice * nm_device_get_master (NMDevice *dev); NMActRequest * nm_device_get_act_request (NMDevice *dev); NMConnection * nm_device_get_connection (NMDevice *dev); +void nm_device_removed (NMDevice *dev); + gboolean nm_device_is_available (NMDevice *dev); gboolean nm_device_has_carrier (NMDevice *dev); -NMConnection * nm_device_generate_connection (NMDevice *device); +NMConnection * nm_device_generate_connection (NMDevice *self, NMDevice *master); -NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, - GSList *connections, - char **specific_object); +gboolean nm_device_master_update_slave_connection (NMDevice *master, + NMDevice *slave, + NMConnection *connection, + GError **error); + +gboolean nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object); gboolean nm_device_complete_connection (NMDevice *device, NMConnection *connection, @@ -272,6 +279,8 @@ gboolean nm_device_complete_connection (NMDevice *device, gboolean nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection); +gboolean nm_device_uses_assumed_connection (NMDevice *device); + gboolean nm_device_can_assume_active_connection (NMDevice *device); gboolean nm_device_spec_match_list (NMDevice *device, const GSList *specs); @@ -294,12 +303,16 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device); * @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie, * because NM is sleeping or not managed for some other reason) * @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs) + * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged + * @NM_UNMANAGED_EXTERNAL_DOWN: %TRUE when unmanaged because !IFF_UP and not created by NM */ typedef enum { - NM_UNMANAGED_NONE = 0x00, - NM_UNMANAGED_DEFAULT = 0x01, - NM_UNMANAGED_INTERNAL = 0x02, - NM_UNMANAGED_USER = 0x04, + NM_UNMANAGED_NONE = 0x00, + NM_UNMANAGED_DEFAULT = 0x01, + NM_UNMANAGED_INTERNAL = 0x02, + NM_UNMANAGED_USER = 0x04, + NM_UNMANAGED_PARENT = 0x08, + NM_UNMANAGED_EXTERNAL_DOWN = 0x10, /* Boundary value */ __NM_UNMANAGED_LAST, @@ -355,6 +368,13 @@ gboolean nm_device_notify_component_added (NMDevice *device, GObject *component) gboolean nm_device_owns_iface (NMDevice *device, const char *iface); +NMConnection *nm_device_new_default_connection (NMDevice *self); + +const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self, gboolean *out_is_assumed); +const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed); + +void nm_device_spawn_iface_helper (NMDevice *self); + G_END_DECLS /* For testing only */ diff --git a/src/devices/team/Makefile.am b/src/devices/team/Makefile.am new file mode 100644 index 00000000..6fea9b3f --- /dev/null +++ b/src/devices/team/Makefile.am @@ -0,0 +1,68 @@ +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_builddir}/src \ + -I${top_srcdir}/src/devices \ + -I${top_srcdir}/src/platform \ + -I${top_srcdir}/include \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ + -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(DBUS_CFLAGS) + +if WITH_TEAMDCTL +AM_CPPFLAGS += ${LIBTEAMDCTL_CFLAGS} +endif + +GLIB_GENERATED = nm-team-enum-types.h nm-team-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_team_enum_types_sources = $(srcdir)/nm-device-team.h + +glue_sources = \ + nm-device-team-glue.h + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) + +pkglib_LTLIBRARIES = libnm-device-plugin-team.la + +SYMBOL_VIS_FILE=$(srcdir)/exports.ver + +libnm_device_plugin_team_la_SOURCES = \ + nm-device-team.c \ + nm-device-team.h \ + nm-team-factory.c \ + nm-team-factory.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_team_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_team_la_LIBADD = \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +if WITH_TEAMDCTL +libnm_device_plugin_team_la_LIBADD += $(LIBTEAMDCTL_LIBS) +endif + +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = $(SYMBOL_VIS_FILE) + +if ENABLE_TESTS + +check-local: + $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + +endif + diff --git a/src/devices/team/Makefile.in b/src/devices/team/Makefile.in new file mode 100644 index 00000000..4ee30e66 --- /dev/null +++ b/src/devices/team/Makefile.in @@ -0,0 +1,845 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@WITH_TEAMDCTL_TRUE@am__append_1 = ${LIBTEAMDCTL_CFLAGS} +@WITH_TEAMDCTL_TRUE@am__append_2 = $(LIBTEAMDCTL_LIBS) +subdir = src/devices/team +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@WITH_TEAMDCTL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libnm_device_plugin_team_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__objects_1 = nm-team-enum-types.lo +am__objects_2 = +am__objects_3 = $(am__objects_1) $(am__objects_2) +am_libnm_device_plugin_team_la_OBJECTS = nm-device-team.lo \ + nm-team-factory.lo $(am__objects_3) +libnm_device_plugin_team_la_OBJECTS = \ + $(am_libnm_device_plugin_team_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libnm_device_plugin_team_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libnm_device_plugin_team_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libnm_device_plugin_team_la_SOURCES) +DIST_SOURCES = $(libnm_device_plugin_team_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src \ + -I${top_srcdir}/src/devices -I${top_srcdir}/src/platform \ + -I${top_srcdir}/include -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ + -DG_LOG_DOMAIN=\""NetworkManager-team"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(DBUS_CFLAGS) \ + $(am__append_1) +GLIB_GENERATED = nm-team-enum-types.h nm-team-enum-types.c +GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM +GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM +nm_team_enum_types_sources = $(srcdir)/nm-device-team.h +glue_sources = \ + nm-device-team-glue.h + +BUILT_SOURCES = $(GLIB_GENERATED) $(glue_sources) +pkglib_LTLIBRARIES = libnm-device-plugin-team.la +SYMBOL_VIS_FILE = $(srcdir)/exports.ver +libnm_device_plugin_team_la_SOURCES = \ + nm-device-team.c \ + nm-device-team.h \ + nm-team-factory.c \ + nm-team-factory.h \ + \ + $(BUILT_SOURCES) + +libnm_device_plugin_team_la_LDFLAGS = \ + -module -avoid-version \ + -Wl,--version-script=$(SYMBOL_VIS_FILE) + +libnm_device_plugin_team_la_LIBADD = $(DBUS_LIBS) $(GUDEV_LIBS) \ + $(am__append_2) +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = $(SYMBOL_VIS_FILE) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/devices/team/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/devices/team/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libnm-device-plugin-team.la: $(libnm_device_plugin_team_la_OBJECTS) $(libnm_device_plugin_team_la_DEPENDENCIES) $(EXTRA_libnm_device_plugin_team_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_device_plugin_team_la_LINK) -rpath $(pkglibdir) $(libnm_device_plugin_team_la_OBJECTS) $(libnm_device_plugin_team_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-team.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-team-enum-types.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-team-factory.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +@ENABLE_TESTS_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: all check check-am install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +include $(GLIB_MAKEFILE) + +@GNOME_CODE_COVERAGE_RULES@ + +%-glue.h: $(top_srcdir)/introspection/%.xml + $(AM_V_GEN) dbus-binding-tool --prefix=$(subst -,_,$(subst -glue.h,,$@)) --mode=glib-server --output=$@ $< + +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ $(top_srcdir)/tools/check-exports.sh $(builddir)/.libs/libnm-device-plugin-team.so $(SYMBOL_VIS_FILE) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/devices/team/exports.ver b/src/devices/team/exports.ver new file mode 100644 index 00000000..24cd848c --- /dev/null +++ b/src/devices/team/exports.ver @@ -0,0 +1,6 @@ +{ +global: + nm_device_factory_create; +local: + *; +}; diff --git a/src/devices/team/nm-device-team-glue.h b/src/devices/team/nm-device-team-glue.h new file mode 100644 index 00000000..405975c8 --- /dev/null +++ b/src/devices/team/nm-device-team-glue.h @@ -0,0 +1,73 @@ +/* Generated by dbus-binding-tool; do not edit! */ + + +#ifndef __dbus_glib_marshal_nm_device_team_MARSHAL_H__ +#define __dbus_glib_marshal_nm_device_team_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +G_END_DECLS + +#endif /* __dbus_glib_marshal_nm_device_team_MARSHAL_H__ */ + +#include +static const DBusGMethodInfo dbus_glib_nm_device_team_methods[] = { +}; + +const DBusGObjectInfo dbus_glib_nm_device_team_object_info = { 1, + dbus_glib_nm_device_team_methods, + 0, +"\0", +"org.freedesktop.NetworkManager.Device.Team\0PropertiesChanged\0\0", +"org.freedesktop.NetworkManager.Device.Team\0HwAddress\0hw_address\0read\0org.freedesktop.NetworkManager.Device.Team\0Carrier\0carrier\0read\0org.freedesktop.NetworkManager.Device.Team\0Slaves\0slaves\0read\0\0" +}; + diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c new file mode 100644 index 00000000..16f1fcc2 --- /dev/null +++ b/src/devices/team/nm-device-team.c @@ -0,0 +1,777 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * Copyright (C) 2013 Jiri Pirko + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-device-team.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" +#include "nm-device-private.h" +#include "nm-platform.h" +#include "nm-dbus-glib-types.h" +#include "nm-dbus-manager.h" +#include "nm-enum-types.h" +#include "nm-team-enum-types.h" +#include "nm-posix-signals.h" +#include "nm-core-internal.h" + +#include "nm-device-team-glue.h" + +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceTeam); + +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)) + +static gboolean teamd_start (NMDevice *device, NMSettingTeam *s_team); + +typedef struct { + struct teamdctl *tdc; + GPid teamd_pid; + guint teamd_process_watch; + guint teamd_timeout; + guint teamd_dbus_watch; +} NMDeviceTeamPrivate; + +enum { + PROP_0, + PROP_SLAVES, + + LAST_PROP +}; + +/******************************************************************/ + +static guint32 +get_generic_capabilities (NMDevice *device) +{ + return NM_DEVICE_CAP_CARRIER_DETECT; +} + +static gboolean +is_available (NMDevice *device) +{ + if (NM_DEVICE_GET_CLASS (device)->is_up) + return NM_DEVICE_GET_CLASS (device)->is_up (device); + return FALSE; +} + +static gboolean +check_connection_available (NMDevice *device, + NMConnection *connection, + const char *specific_object) +{ + /* Connections are always available because the carrier state is determined + * by the team port carrier states, not the team's state. + */ + return TRUE; +} + +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + const char *iface; + NMSettingTeam *s_team; + + if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_team = nm_connection_get_setting_team (connection); + if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) + return FALSE; + + /* Team connections must specify the virtual interface name */ + iface = nm_connection_get_interface_name (connection); + if (!iface || strcmp (nm_device_get_iface (device), iface)) + return FALSE; + + /* FIXME: match team properties like mode, etc? */ + + return TRUE; +} + +static gboolean +complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMSettingTeam *s_team; + + nm_utils_complete_generic (connection, + NM_SETTING_TEAM_SETTING_NAME, + existing_connections, + NULL, + _("Team connection"), + "team", + TRUE); + + s_team = nm_connection_get_setting_team (connection); + if (!s_team) { + s_team = (NMSettingTeam *) nm_setting_team_new (); + nm_connection_add_setting (connection, NM_SETTING (s_team)); + } + + return TRUE; +} + +static gboolean +ensure_teamd_connection (NMDevice *device) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + int err; + + if (priv->tdc) + return TRUE; + + priv->tdc = teamdctl_alloc (); + g_assert (priv->tdc); + err = teamdctl_connect (priv->tdc, nm_device_get_iface (device), NULL, NULL); + if (err != 0) { + _LOGE (LOGD_TEAM, "failed to connect to teamd (err=%d)", err); + teamdctl_free (priv->tdc); + priv->tdc = NULL; + } + + return !!priv->tdc; +} + +static void +update_connection (NMDevice *device, NMConnection *connection) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMSettingTeam *s_team = nm_connection_get_setting_team (connection); + + if (!s_team) { + 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); + + teamd_start (device, s_team); + if (NM_DEVICE_TEAM_GET_PRIVATE (device)->teamd_pid > 0 && ensure_teamd_connection (device)) { + const char *config = NULL; + int err; + + 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); + } +} + +/******************************************************************/ + +static gboolean +master_update_slave_connection (NMDevice *self, + NMDevice *slave, + NMConnection *connection, + GError **error) +{ + NMSettingTeamPort *s_port; + char *port_config = NULL; + int err = 0; + struct teamdctl *tdc; + const char *team_port_config = NULL; + const char *iface = nm_device_get_iface (self); + const char *iface_slave = nm_device_get_iface (slave); + + tdc = teamdctl_alloc (); + if (!tdc) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master %s (out of memory?)", + iface_slave, iface); + g_return_val_if_reached (FALSE); + } + + err = teamdctl_connect (tdc, iface, NULL, NULL); + if (err) { + teamdctl_free (tdc); + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to connect to teamd for master %s (err=%d)", + iface_slave, iface, err); + return FALSE; + } + + err = teamdctl_port_config_get_raw_direct (tdc, iface_slave, (char **)&team_port_config); + port_config = g_strdup (team_port_config); + teamdctl_free (tdc); + if (err) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "update slave connection for slave '%s' failed to get configuration from teamd master %s (err=%d)", + iface_slave, iface, err); + g_free (port_config); + return FALSE; + } + + s_port = nm_connection_get_setting_team_port (connection); + if (!s_port) { + s_port = (NMSettingTeamPort *) nm_setting_team_port_new (); + nm_connection_add_setting (connection, NM_SETTING (s_port)); + } + + g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); + g_free (port_config); + + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_MASTER, iface, + NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_TEAM_SETTING_NAME, + NULL); + return TRUE; +} + +/******************************************************************/ + +static void +teamd_timeout_remove (NMDevice *device) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + + if (priv->teamd_timeout) { + g_source_remove (priv->teamd_timeout); + priv->teamd_timeout = 0; + } +} + +static void +teamd_cleanup (NMDevice *device, gboolean device_state_failed) +{ + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + + if (priv->teamd_dbus_watch) { + g_bus_unwatch_name (priv->teamd_dbus_watch); + priv->teamd_dbus_watch = 0; + } + + if (priv->teamd_process_watch) { + g_source_remove (priv->teamd_process_watch); + priv->teamd_process_watch = 0; + } + + if (priv->teamd_pid > 0) { + nm_utils_kill_child_async (priv->teamd_pid, SIGTERM, LOGD_TEAM, "teamd", 2000, NULL, NULL); + priv->teamd_pid = 0; + } + + if (priv->tdc) { + teamdctl_disconnect (priv->tdc); + teamdctl_free (priv->tdc); + priv->tdc = NULL; + } + + teamd_timeout_remove (device); + + if (device_state_failed) { + if (nm_device_is_activating (device) || + (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } +} + +static gboolean +teamd_timeout_cb (gpointer user_data) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDevice *device = NM_DEVICE (self); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + + g_return_val_if_fail (priv->teamd_timeout, FALSE); + + _LOGI (LOGD_TEAM, "teamd timed out."); + teamd_cleanup (device, TRUE); + + return FALSE; +} + +static void +teamd_dbus_appeared (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + gboolean success; + + g_return_if_fail (priv->teamd_dbus_watch); + + _LOGI (LOGD_TEAM, "teamd appeared on D-Bus"); + teamd_timeout_remove (device); + + success = ensure_teamd_connection (device); + if (nm_device_get_state (device) == NM_DEVICE_STATE_PREPARE) { + if (success) + nm_device_activate_schedule_stage2_device_config (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); + return; + } +} + +static void +teamd_dbus_vanished (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + + g_return_if_fail (priv->teamd_dbus_watch); + + if (priv->teamd_timeout) { + /* 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, until the + * startup timeout is over. + * + * Note that g_bus_watch_name is guaranteed to alternate vanished/appeared signals, + * so we won't hit this condition again (because the next signal is either 'appeared' + * or 'timeout'). */ + _LOGD (LOGD_TEAM, "teamd vanished from D-Bus (ignored)"); + return; + } + + _LOGI (LOGD_TEAM, "teamd vanished from D-Bus"); + teamd_cleanup (device, TRUE); +} + +static void +teamd_process_watch_cb (GPid pid, gint status, gpointer user_data) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + NMDevice *device = NM_DEVICE (self); + + g_return_if_fail (priv->teamd_process_watch); + + _LOGI (LOGD_TEAM, "teamd died with status %d", status); + priv->teamd_process_watch = 0; + priv->teamd_pid = 0; + teamd_cleanup (device, TRUE); +} + +static void +teamd_child_setup (gpointer user_data G_GNUC_UNUSED) +{ + /* We are in the child process at this point. + * Give child it's own program group for signal + * separation. + */ + pid_t pid = getpid (); + setpgid (pid, pid); + + /* + * We blocked signals in main(). We need to restore original signal + * mask for avahi-autoipd here so that it can receive signals. + */ + nm_unblock_posix_signals (NULL); +} + +static gboolean +teamd_start (NMDevice *device, NMSettingTeam *s_team) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + const char *iface = nm_device_get_ip_iface (device); + char *tmp_str = NULL; + const char *config; + const char *teamd_binary; + GPtrArray *argv; + GError *error = NULL; + gboolean ret; + int status; + + if (priv->teamd_dbus_watch || + priv->teamd_process_watch || + priv->teamd_pid > 0 || + priv->tdc || + priv->teamd_timeout) + { + /* Just return if teamd_start() was already called */ + return TRUE; + } + + teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL); + if (!teamd_binary) { + _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found"); + return FALSE; + } + + /* Kill teamd for same named device first if it is there */ + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (gpointer) teamd_binary); + g_ptr_array_add (argv, (gpointer) "-k"); + g_ptr_array_add (argv, (gpointer) "-t"); + g_ptr_array_add (argv, (gpointer) iface); + g_ptr_array_add (argv, NULL); + + _LOGD (LOGD_TEAM, "running: %s", + (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + g_clear_pointer (&tmp_str, g_free); + + ret = g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, nm_unblock_posix_signals, NULL, NULL, NULL, &status, &error); + g_ptr_array_free (argv, TRUE); + + /* Start teamd now */ + argv = g_ptr_array_new (); + g_ptr_array_add (argv, (gpointer) teamd_binary); + g_ptr_array_add (argv, (gpointer) "-o"); + g_ptr_array_add (argv, (gpointer) "-n"); + g_ptr_array_add (argv, (gpointer) "-U"); + g_ptr_array_add (argv, (gpointer) "-D"); + g_ptr_array_add (argv, (gpointer) "-N"); + g_ptr_array_add (argv, (gpointer) "-t"); + g_ptr_array_add (argv, (gpointer) iface); + + config = nm_setting_team_get_config(s_team); + if (config) { + g_ptr_array_add (argv, (gpointer) "-c"); + g_ptr_array_add (argv, (gpointer) config); + } + + if (nm_logging_enabled (LOGL_DEBUG, LOGD_TEAM)) + g_ptr_array_add (argv, (gpointer) "-gg"); + g_ptr_array_add (argv, NULL); + + _LOGD (LOGD_TEAM, "running: %s", + (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); + g_clear_pointer (&tmp_str, g_free); + + /* Start a timeout for teamd to appear at D-Bus */ + priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device); + + /* Register D-Bus name watcher */ + tmp_str = g_strdup_printf ("org.libteam.teamd.%s", iface); + priv->teamd_dbus_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, + tmp_str, + G_BUS_NAME_WATCHER_FLAGS_NONE, + teamd_dbus_appeared, + teamd_dbus_vanished, + device, + NULL); + g_free (tmp_str); + + ret = g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, + &teamd_child_setup, NULL, &priv->teamd_pid, &error); + g_ptr_array_free (argv, TRUE); + if (!ret) { + _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); + g_clear_error (&error); + teamd_cleanup (device, FALSE); + return FALSE; + } + + /* Monitor the child process so we know when it dies */ + priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid, + teamd_process_watch_cb, + device); + + _LOGI (LOGD_TEAM, "Activation: (team) started teamd..."); + return TRUE; +} + +static void +teamd_stop (NMDevice *device) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); + + if (priv->teamd_pid > 0) + _LOGI (LOGD_TEAM, "Deactivation: stopping teamd..."); + else + _LOGD (LOGD_TEAM, "Deactivation: stopping teamd (not started)..."); + teamd_cleanup (device, FALSE); +} + +static NMActStageReturn +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) +{ + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + NMConnection *connection; + NMSettingTeam *s_team; + + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason); + if (ret == NM_ACT_STAGE_RETURN_SUCCESS) { + connection = nm_device_get_connection (device); + g_assert (connection); + s_team = nm_connection_get_setting_team (connection); + g_assert (s_team); + if (teamd_start (device, s_team)) + ret = NM_ACT_STAGE_RETURN_POSTPONE; + else + ret = NM_ACT_STAGE_RETURN_FAILURE; + } + return ret; +} + +static void +deactivate (NMDevice *device) +{ + teamd_stop (device); +} + +static gboolean +enslave_slave (NMDevice *device, + NMDevice *slave, + NMConnection *connection, + gboolean configure) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device); + gboolean success = TRUE, no_firmware = FALSE; + const char *slave_iface = nm_device_get_ip_iface (slave); + NMSettingTeamPort *s_team_port; + + nm_device_master_check_slave_physical_port (device, slave, LOGD_TEAM); + + if (configure) { + nm_device_take_down (slave, TRUE); + + s_team_port = nm_connection_get_setting_team_port (connection); + if (s_team_port) { + const char *config = nm_setting_team_port_get_config (s_team_port); + + if (config) { + if (!priv->tdc) { + _LOGW (LOGD_TEAM, "enslaved team port %s config not changed, not connected to teamd", + slave_iface); + } else { + int err; + char *sanitized_config; + + sanitized_config = g_strdelimit (g_strdup (config), "\r\n", ' '); + err = teamdctl_port_config_update_raw (priv->tdc, slave_iface, sanitized_config); + g_free (sanitized_config); + if (err != 0) { + _LOGE (LOGD_TEAM, "failed to update config for port %s (err=%d)", + slave_iface, err); + return FALSE; + } + } + } + } + success = nm_platform_link_enslave (nm_device_get_ip_ifindex (device), + nm_device_get_ip_ifindex (slave)); + nm_device_bring_up (slave, TRUE, &no_firmware); + + if (!success) + return FALSE; + + _LOGI (LOGD_TEAM, "enslaved team port %s", slave_iface); + } else + _LOGI (LOGD_TEAM, "team port %s was enslaved", slave_iface); + + g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); + + return TRUE; +} + +static gboolean +release_slave (NMDevice *device, + NMDevice *slave, + gboolean configure) +{ + NMDeviceTeam *self = NM_DEVICE_TEAM (device); + gboolean success = TRUE, no_firmware = FALSE; + + if (configure) { + success = nm_platform_link_release (nm_device_get_ip_ifindex (device), + nm_device_get_ip_ifindex (slave)); + + if (success) + _LOGI (LOGD_TEAM, "released team port %s", nm_device_get_ip_iface (slave)); + else + _LOGW (LOGD_TEAM, "failed to release team port %s", nm_device_get_ip_iface (slave)); + } else + _LOGI (LOGD_TEAM, "team port %s was released", nm_device_get_ip_iface (slave)); + + if (success) + g_object_notify (G_OBJECT (device), NM_DEVICE_TEAM_SLAVES); + + if (configure) { + /* Kernel team code "closes" the port when releasing it, (which clears + * IFF_UP), so we must bring it back up here to ensure carrier changes and + * other state is noticed by the now-released port. + */ + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) + _LOGW (LOGD_TEAM, "released team port %s could not be brought up", + nm_device_get_ip_iface (slave)); + } + + return success; +} + +/******************************************************************/ + +NMDevice * +nm_device_team_new (NMPlatformLink *platform_device) +{ + g_return_val_if_fail (platform_device != NULL, NULL); + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, + NM_DEVICE_PLATFORM_DEVICE, platform_device, + NM_DEVICE_DRIVER, "team", + NM_DEVICE_TYPE_DESC, "Team", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, + NM_DEVICE_IS_MASTER, TRUE, + NULL); +} + +NMDevice * +nm_device_team_new_for_connection (NMConnection *connection, GError **error) +{ + const char *iface; + + g_return_val_if_fail (connection != NULL, NULL); + + iface = nm_connection_get_interface_name (connection); + g_return_val_if_fail (iface != NULL, NULL); + + if ( !nm_platform_team_add (iface) + && nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) { + g_set_error (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "failed to create team master interface '%s' for connection '%s': %s", + iface, nm_connection_get_id (connection), + nm_platform_get_error_msg ()); + return NULL; + } + + return (NMDevice *) g_object_new (NM_TYPE_DEVICE_TEAM, + NM_DEVICE_IFACE, iface, + NM_DEVICE_DRIVER, "team", + NM_DEVICE_TYPE_DESC, "Team", + NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_TEAM, + NM_DEVICE_IS_MASTER, TRUE, + NULL); +} + +static void +nm_device_team_init (NMDeviceTeam * self) +{ +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + GPtrArray *slaves; + GSList *list, *iter; + + switch (prop_id) { + break; + case PROP_SLAVES: + slaves = g_ptr_array_new (); + list = nm_device_master_get_slaves (NM_DEVICE (object)); + for (iter = list; iter; iter = iter->next) + g_ptr_array_add (slaves, g_strdup (nm_device_get_path (NM_DEVICE (iter->data)))); + g_slist_free (list); + g_value_take_boxed (value, slaves); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + teamd_cleanup (NM_DEVICE (object), FALSE); + + G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); +} + +static void +nm_device_team_class_init (NMDeviceTeamClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceTeamPrivate)); + + parent_class->connection_type = NM_SETTING_TEAM_SETTING_NAME; + + /* virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->is_available = is_available; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->check_connection_available = check_connection_available; + parent_class->complete_connection = complete_connection; + parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; + + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->deactivate = deactivate; + parent_class->enslave_slave = enslave_slave; + parent_class->release_slave = release_slave; + + /* properties */ + g_object_class_install_property + (object_class, PROP_SLAVES, + g_param_spec_boxed (NM_DEVICE_TEAM_SLAVES, "", "", + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), + G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_team_object_info); +} diff --git a/src/devices/team/nm-device-team.h b/src/devices/team/nm-device-team.h new file mode 100644 index 00000000..26ba5737 --- /dev/null +++ b/src/devices/team/nm-device-team.h @@ -0,0 +1,56 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * Copyright (C) 2013 Jiri Pirko + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __NETWORKMANAGER_DEVICE_TEAM_H__ +#define __NETWORKMANAGER_DEVICE_TEAM_H__ + +#include + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_TEAM (nm_device_team_get_type ()) +#define NM_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_TEAM, NMDeviceTeam)) +#define NM_DEVICE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_TEAM, NMDeviceTeamClass)) +#define NM_IS_DEVICE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_TEAM)) +#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)) + +#define NM_DEVICE_TEAM_SLAVES "slaves" + +typedef struct { + NMDevice parent; +} NMDeviceTeam; + +typedef struct { + NMDeviceClass parent; + +} NMDeviceTeamClass; + + +GType nm_device_team_get_type (void); + +NMDevice *nm_device_team_new (NMPlatformLink *platform_device); +NMDevice *nm_device_team_new_for_connection (NMConnection *connection, GError **error); + +G_END_DECLS + +#endif /* NM_DEVICE_TEAM_H */ diff --git a/src/devices/team/nm-team-enum-types.c b/src/devices/team/nm-team-enum-types.c new file mode 100644 index 00000000..5ac3494d --- /dev/null +++ b/src/devices/team/nm-team-enum-types.c @@ -0,0 +1,12 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#include "nm-team-enum-types.h" + +#include "nm-device-team.h" + + + + diff --git a/src/devices/team/nm-team-enum-types.h b/src/devices/team/nm-team-enum-types.h new file mode 100644 index 00000000..136cadc2 --- /dev/null +++ b/src/devices/team/nm-team-enum-types.h @@ -0,0 +1,17 @@ + + + +/* Generated by glib-mkenums. Do not edit */ + +#ifndef __NM_TEAM_ENUM_TYPES_H__ +#define __NM_TEAM_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +G_END_DECLS + +#endif /* __NM_TEAM_ENUM_TYPES_H__ */ + + + diff --git a/src/devices/team/nm-team-factory.c b/src/devices/team/nm-team-factory.c new file mode 100644 index 00000000..cb887cac --- /dev/null +++ b/src/devices/team/nm-team-factory.c @@ -0,0 +1,93 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "nm-device-factory.h" +#include "nm-team-factory.h" +#include "nm-device-team.h" +#include "nm-logging.h" +#include "nm-platform.h" +#include "nm-core-internal.h" + +static GType nm_team_factory_get_type (void); + +static void device_factory_interface_init (NMDeviceFactory *factory_iface); + +G_DEFINE_TYPE_EXTENDED (NMTeamFactory, nm_team_factory, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_FACTORY, device_factory_interface_init)) + +/************************************************************************/ + +G_MODULE_EXPORT NMDeviceFactory * +nm_device_factory_create (GError **error) +{ + return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL); +} + +/************************************************************************/ + +static NMDevice * +new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) +{ + if (plink->type == NM_LINK_TYPE_TEAM) + return nm_device_team_new (plink); + return NULL; +} + +static NMDevice * +create_virtual_device_for_connection (NMDeviceFactory *factory, + NMConnection *connection, + NMDevice *parent, + GError **error) +{ + if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) + return nm_device_team_new_for_connection (connection, error); + return NULL; +} + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_TEAM; +} + +/************************************************************************/ + +static void +nm_team_factory_init (NMTeamFactory *self) +{ +} + +static void +device_factory_interface_init (NMDeviceFactory *factory_iface) +{ + factory_iface->new_link = new_link; + factory_iface->create_virtual_device_for_connection = create_virtual_device_for_connection; + factory_iface->get_device_type = get_device_type; +} + +static void +nm_team_factory_class_init (NMTeamFactoryClass *klass) +{ +} diff --git a/src/devices/team/nm-team-factory.h b/src/devices/team/nm-team-factory.h new file mode 100644 index 00000000..2f02ac57 --- /dev/null +++ b/src/devices/team/nm-team-factory.h @@ -0,0 +1,37 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_TEAM_FACTORY_H__ +#define __NETWORKMANAGER_TEAM_FACTORY_H__ + +#include + +#define NM_TYPE_TEAM_FACTORY (nm_team_factory_get_type ()) +#define NM_TEAM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEAM_FACTORY, NMTeamFactory)) + +typedef struct { + GObject parent; +} NMTeamFactory; + +typedef struct { + GObjectClass parent; +} NMTeamFactoryClass; + +#endif /* __NETWORKMANAGER_TEAM_FACTORY_H__ */ diff --git a/src/devices/wifi/Makefile.am b/src/devices/wifi/Makefile.am index 5f3ce286..230c00ac 100644 --- a/src/devices/wifi/Makefile.am +++ b/src/devices/wifi/Makefile.am @@ -7,21 +7,17 @@ SUBDIRS=. tests AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-wifi-enum-types.h nm-wifi-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM diff --git a/src/devices/wifi/Makefile.in b/src/devices/wifi/Makefile.in index cbf6826b..175dd900 100644 --- a/src/devices/wifi/Makefile.in +++ b/src/devices/wifi/Makefile.in @@ -261,6 +261,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -384,6 +386,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -403,6 +406,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -429,7 +433,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -512,21 +516,17 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ -I${top_srcdir}/src/supplicant-manager \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(DBUS_CFLAGS) GLIB_GENERATED = nm-wifi-enum-types.h nm-wifi-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM diff --git a/src/devices/wifi/exports.ver b/src/devices/wifi/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wifi/exports.ver +++ b/src/devices/wifi/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 85214a70..0f5aa164 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -25,18 +25,16 @@ */ #include "config.h" + #include #include #include #include #include -#include -#include #include #include #include #include -#include #include #include @@ -53,14 +51,18 @@ #include "nm-manager.h" #include "nm-enum-types.h" #include "nm-dbus-manager.h" +#include "nm-platform.h" #include "nm-wifi-enum-types.h" /* This is a bug; but we can't really change API now... */ -#include "NetworkManagerVPN.h" +#include "nm-vpn-dbus-interface.h" #include "nm-device-olpc-mesh-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceOlpcMesh); + G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) #define NM_DEVICE_OLPC_MESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshPrivate)) @@ -80,19 +82,6 @@ struct _NMDeviceOlpcMeshPrivate { /*******************************************************************/ -static GQuark -nm_olpc_mesh_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-mesh-error"); - return quark; -} - -#define NM_OLPC_MESH_ERROR (nm_olpc_mesh_error_quark ()) - -/*******************************************************************/ - static gboolean check_connection_compatible (NMDevice *device, NMConnection *connection) { @@ -149,19 +138,17 @@ complete_connection (NMDevice *device, } if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) { - const guint8 anycast[ETH_ALEN] = { 0xC0, 0x27, 0xC0, 0x27, 0xC0, 0x27 }; + const char *anycast = "c0:27:c0:27:c0:27"; - tmp = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (tmp, anycast, sizeof (anycast)); - g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, anycast, NULL); } nm_utils_complete_generic (connection, NM_SETTING_OLPC_MESH_SETTING_NAME, existing_connections, - _("Mesh %d"), + NULL, + _("Mesh"), NULL, FALSE); /* No IPv6 by default */ @@ -171,28 +158,27 @@ complete_connection (NMDevice *device, /****************************************************************************/ static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); + NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (device); NMActStageReturn ret; gboolean scanning; - ret = NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->act_stage1_prepare (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; /* disconnect companion device, if it is connected */ if (nm_device_get_act_request (NM_DEVICE (priv->companion))) { - nm_log_info (LOGD_OLPC, "(%s): disconnecting companion device %s", - nm_device_get_iface (dev), - nm_device_get_iface (priv->companion)); + _LOGI (LOGD_OLPC, "disconnecting companion device %s", + nm_device_get_iface (priv->companion)); /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ nm_device_state_changed (NM_DEVICE (priv->companion), NM_DEVICE_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); - nm_log_info (LOGD_OLPC, "(%s): companion %s disconnected", - nm_device_get_iface (dev), - nm_device_get_iface (priv->companion)); + NM_DEVICE_STATE_REASON_USER_REQUESTED); + _LOGI (LOGD_OLPC, "companion %s disconnected", + nm_device_get_iface (priv->companion)); } @@ -218,16 +204,16 @@ _mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel) } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); NMConnection *connection; NMSettingOlpcMesh *s_mesh; guint32 channel; - const GByteArray *anycast_addr_array; - guint8 *anycast_addr = NULL; + GBytes *ssid; + const char *anycast_addr; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_mesh = nm_connection_get_setting_olpc_mesh (connection); @@ -236,25 +222,25 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) channel = nm_setting_olpc_mesh_get_channel (s_mesh); if (channel != 0) _mesh_set_channel (self, channel); - nm_platform_mesh_set_ssid (nm_device_get_ifindex (dev), - nm_setting_olpc_mesh_get_ssid (s_mesh)); - anycast_addr_array = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); - if (anycast_addr_array) - anycast_addr = anycast_addr_array->data; + ssid = nm_setting_olpc_mesh_get_ssid (s_mesh); + nm_platform_mesh_set_ssid (nm_device_get_ifindex (device), + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + + anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh); + nm_device_set_dhcp_anycast_address (device, anycast_addr); - nm_device_set_dhcp_anycast_address (dev, anycast_addr); return NM_ACT_STAGE_RETURN_SUCCESS; } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (dev); + NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (device); if (!NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->companion) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because companion not found", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because companion not found"); return FALSE; } @@ -310,12 +296,11 @@ companion_state_changed_cb (NMDeviceWifi *companion, || state > NM_DEVICE_STATE_ACTIVATED) return; - nm_log_dbg (LOGD_OLPC, "(%s): disconnecting mesh due to companion connectivity", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_OLPC, "disconnecting mesh due to companion connectivity"); /* FIXME: VPN stuff here is a bug; but we can't really change API now... */ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); + NM_DEVICE_STATE_REASON_USER_REQUESTED); } static gboolean @@ -343,24 +328,21 @@ static gboolean check_companion (NMDeviceOlpcMesh *self, NMDevice *other) { NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); - const guint8 *my_addr, *their_addr; - guint their_addr_len; + const char *my_addr, *their_addr; if (!NM_IS_DEVICE_WIFI (other)) return FALSE; - my_addr = nm_device_get_hw_address (NM_DEVICE (self), NULL); - their_addr = nm_device_get_hw_address (other, &their_addr_len); - if ( (their_addr_len != ETH_ALEN) - || (memcmp (my_addr, their_addr, ETH_ALEN) != 0)) + my_addr = nm_device_get_hw_address (NM_DEVICE (self)); + their_addr = nm_device_get_hw_address (other); + if (!nm_utils_hwaddr_matches (my_addr, -1, their_addr, -1)) return FALSE; g_assert (priv->companion == NULL); priv->companion = g_object_ref (other); - nm_log_info (LOGD_OLPC, "(%s): found companion WiFi device %s", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_iface (other)); + _LOGI (LOGD_OLPC, "found companion WiFi device %s", + nm_device_get_iface (other)); g_signal_connect (G_OBJECT (other), "state-changed", G_CALLBACK (companion_state_changed_cb), self); @@ -471,13 +453,8 @@ constructor (GType type, self = NM_DEVICE_OLPC_MESH (object); - nm_log_dbg (LOGD_HW | LOGD_OLPC, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &caps)) { - nm_log_warn (LOGD_HW | LOGD_OLPC, "(%s): failed to initialize WiFi driver", - nm_device_get_iface (NM_DEVICE (self))); + _LOGW (LOGD_HW | LOGD_OLPC, "failed to initialize WiFi driver"); g_object_unref (object); return NULL; } @@ -562,24 +539,20 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_COMPANION, - g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, - "Companion device", - "Companion device object path", + g_param_spec_boxed (NM_DEVICE_OLPC_MESH_COMPANION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVE_CHANNEL, - g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, - "Active channel", - "Active channel", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_param_spec_uint (NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_olpc_mesh_object_info); - - dbus_g_error_domain_register (NM_OLPC_MESH_ERROR, NULL, NM_TYPE_OLPC_MESH_ERROR); } diff --git a/src/devices/wifi/nm-device-olpc-mesh.h b/src/devices/wifi/nm-device-olpc-mesh.h index c25dd8e5..67d83fb0 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.h +++ b/src/devices/wifi/nm-device-olpc-mesh.h @@ -25,11 +25,10 @@ * (C) Copyright 2009 One Laptop per Child */ -#ifndef NM_DEVICE_OLPC_MESH_H -#define NM_DEVICE_OLPC_MESH_H +#ifndef __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ +#define __NETWORKMANAGER_DEVICE_OLPC_MESH_H__ #include -#include #include "nm-device.h" @@ -42,13 +41,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_OLPC_MESH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OLPC_MESH)) #define NM_DEVICE_OLPC_MESH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OLPC_MESH, NMDeviceOlpcMeshClass)) -typedef enum -{ - NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH = 0, /*< nick=ConnectionNotMesh >*/ - NM_OLPC_MESH_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ -} NMOlpcMeshError; - #define NM_DEVICE_OLPC_MESH_COMPANION "companion" #define NM_DEVICE_OLPC_MESH_BITRATE "bitrate" #define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel" diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 95173cf4..dd7754b3 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -19,12 +19,13 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include #include #include -#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #include "nm-glib-compat.h" @@ -52,9 +52,10 @@ #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" #include "nm-setting-ip4-config.h" +#include "nm-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-platform.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-settings-connection.h" #include "nm-enum-types.h" #include "nm-dbus-glib-types.h" @@ -76,6 +77,8 @@ static void impl_device_request_scan (NMDeviceWifi *device, #include "nm-device-wifi-glue.h" +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceWifi); /* All of these are in seconds */ #define SCAN_INTERVAL_MIN 3 @@ -115,8 +118,8 @@ static guint signals[LAST_SIGNAL] = { 0 }; struct _NMDeviceWifiPrivate { gboolean disposed; - guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */ - guint8 initial_hw_addr[ETH_ALEN]; /* Initial MAC address (as seen when NM starts) */ + char * perm_hw_addr; /* Permanent MAC address */ + char * initial_hw_addr; /* Initial MAC address (as seen when NM starts) */ gint8 invalid_strength_counter; @@ -192,19 +195,6 @@ static void remove_supplicant_interface_error_handler (NMDeviceWifi *self); /*****************************************************************/ -#define NM_WIFI_ERROR (nm_wifi_error_quark ()) - -static GQuark -nm_wifi_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-wifi-error"); - return quark; -} - -/*****************************************************************/ - static GObject* constructor (GType type, guint n_construct_params, @@ -223,22 +213,15 @@ constructor (GType type, self = NM_DEVICE_WIFI (object); priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_dbg (LOGD_HW | LOGD_WIFI, "(%s): kernel ifindex %d", - nm_device_get_iface (NM_DEVICE (self)), - nm_device_get_ifindex (NM_DEVICE (self))); - if (!nm_platform_wifi_get_capabilities (nm_device_get_ifindex (NM_DEVICE (self)), &priv->capabilities)) { - nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s): failed to initialize WiFi driver", - nm_device_get_iface (NM_DEVICE (self))); + _LOGW (LOGD_HW | LOGD_WIFI, "failed to initialize WiFi driver"); g_object_unref (object); return NULL; } - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) { - nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver supports Access Point (AP) mode", - nm_device_get_iface (NM_DEVICE (self))); - } + if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + _LOGI (LOGD_HW | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ priv->sup_mgr = nm_supplicant_manager_get (); @@ -260,13 +243,12 @@ supplicant_interface_acquire (NMDeviceWifi *self) nm_device_get_iface (NM_DEVICE (self)), TRUE); if (priv->sup_iface == NULL) { - nm_log_err (LOGD_WIFI, "Couldn't initialize supplicant interface for %s.", - nm_device_get_iface (NM_DEVICE (self))); + _LOGE (LOGD_WIFI, "Couldn't initialize supplicant interface"); return FALSE; } if (nm_supplicant_interface_get_state (priv->sup_iface) < NM_SUPPLICANT_INTERFACE_STATE_READY) - nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", TRUE); + nm_device_add_pending_action (NM_DEVICE (self), "waiting for supplicant", FALSE); g_signal_connect (priv->sup_iface, NM_SUPPLICANT_INTERFACE_STATE, @@ -309,9 +291,8 @@ supplicant_interface_release (NMDeviceWifi *self) /* Reset the scan interval to be pretty frequent when disconnected */ priv->scan_interval = SCAN_INTERVAL_MIN + SCAN_INTERVAL_STEP; - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): reset scanning interval to %d seconds", - nm_device_get_iface (NM_DEVICE (self)), - priv->scan_interval); + _LOGD (LOGD_WIFI_SCAN, "reset scanning interval to %d seconds", + priv->scan_interval); if (priv->scanlist_cull_id) { g_source_remove (priv->scanlist_cull_id); @@ -370,9 +351,8 @@ find_active_ap (NMDeviceWifi *self, gboolean match_hidden) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - const char *iface = nm_device_get_iface (NM_DEVICE (self)); int ifindex = nm_device_get_ifindex (NM_DEVICE (self)); - struct ether_addr bssid; + guint8 bssid[ETH_ALEN]; GByteArray *ssid; GSList *iter; int i = 0; @@ -382,22 +362,18 @@ find_active_ap (NMDeviceWifi *self, NM80211Mode devmode; guint32 devfreq; - nm_platform_wifi_get_bssid (ifindex, &bssid); - nm_log_dbg (LOGD_WIFI, "(%s): active BSSID: %02x:%02x:%02x:%02x:%02x:%02x", - iface, - bssid.ether_addr_octet[0], bssid.ether_addr_octet[1], - bssid.ether_addr_octet[2], bssid.ether_addr_octet[3], - bssid.ether_addr_octet[4], bssid.ether_addr_octet[5]); + nm_platform_wifi_get_bssid (ifindex, bssid); + _LOGD (LOGD_WIFI, "active BSSID: %02x:%02x:%02x:%02x:%02x:%02x", + bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - if (!nm_ethernet_address_is_valid (&bssid)) + if (!nm_ethernet_address_is_valid (bssid, ETH_ALEN)) return NULL; ssid = nm_platform_wifi_get_ssid (ifindex); - nm_log_dbg (LOGD_WIFI, "(%s): active SSID: %s%s%s", - iface, - ssid ? "'" : "", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - ssid ? "'" : ""); + _LOGD (LOGD_WIFI, "active SSID: %s%s%s", + ssid ? "'" : "", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + ssid ? "'" : ""); devmode = nm_platform_wifi_get_mode (ifindex); devfreq = nm_platform_wifi_get_frequency (ifindex); @@ -407,50 +383,54 @@ find_active_ap (NMDeviceWifi *self, * and therefore it won't get matched the first time around. */ while (i++ < (match_hidden ? 2 : 1)) { - nm_log_dbg (LOGD_WIFI, " Pass #%d %s", i, i > 1 ? "(ignoring SSID)" : ""); + _LOGD (LOGD_WIFI, " Pass #%d %s", i, i > 1 ? "(ignoring SSID)" : ""); /* Find this SSID + BSSID in the device's AP list */ for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { NMAccessPoint *ap = NM_AP (iter->data); - const struct ether_addr *ap_bssid = nm_ap_get_address (ap); + const char *ap_bssid = nm_ap_get_address (ap); const GByteArray *ap_ssid = nm_ap_get_ssid (ap); NM80211Mode apmode; guint32 apfreq; - nm_log_dbg (LOGD_WIFI, " AP: %s%s%s %02x:%02x:%02x:%02x:%02x:%02x", - ap_ssid ? "'" : "", - ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", - ap_ssid ? "'" : "", - ap_bssid->ether_addr_octet[0], ap_bssid->ether_addr_octet[1], - ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], - ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); + _LOGD (LOGD_WIFI, " AP: %s%s%s %s", + ap_ssid ? "'" : "", + ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", + ap_ssid ? "'" : "", + str_if_set (ap_bssid, "(none)")); if (ap == ignore_ap) { - nm_log_dbg (LOGD_WIFI, " ignored"); + _LOGD (LOGD_WIFI, " ignored"); continue; } - if (memcmp (bssid.ether_addr_octet, ap_bssid->ether_addr_octet, ETH_ALEN)) { - nm_log_dbg (LOGD_WIFI, " BSSID mismatch"); + if (!nm_utils_hwaddr_matches (bssid, ETH_ALEN, ap_bssid, -1)) { + _LOGD (LOGD_WIFI, " BSSID mismatch"); continue; } - if ((i == 0) && !nm_utils_same_ssid (ssid, ap_ssid, TRUE)) { - nm_log_dbg (LOGD_WIFI, " SSID mismatch"); - continue; + if (i == 0) { + if ( (ssid && !ap_ssid) + || (ap_ssid && !ssid) + || (ssid && ap_ssid && !nm_utils_same_ssid (ssid->data, ssid->len, + ap_ssid->data, ap_ssid->len, + TRUE))) { + _LOGD (LOGD_WIFI, " SSID mismatch"); + continue; + } } apmode = nm_ap_get_mode (ap); if (devmode != apmode) { - nm_log_dbg (LOGD_WIFI, " mode mismatch (device %d, ap %d)", - devmode, apmode); + _LOGD (LOGD_WIFI, " mode mismatch (device %d, ap %d)", + devmode, apmode); continue; } apfreq = nm_ap_get_freq (ap); if (devfreq != apfreq) { - nm_log_dbg (LOGD_WIFI, " frequency mismatch (device %u, ap %u)", - devfreq, apfreq); + _LOGD (LOGD_WIFI, " frequency mismatch (device %u, ap %u)", + devfreq, apfreq); if (match_nofreq == NULL) match_nofreq = ap; @@ -463,7 +443,7 @@ find_active_ap (NMDeviceWifi *self, } // FIXME: handle security settings here too - nm_log_dbg (LOGD_WIFI, " matched"); + _LOGD (LOGD_WIFI, " matched"); active_ap = ap; goto done; } @@ -482,22 +462,19 @@ find_active_ap (NMDeviceWifi *self, * we can't match the AP based on frequency at all, just give up. */ if (match_nofreq && ((found_a_band != found_bg_band) || (devfreq == 0))) { - const struct ether_addr *ap_bssid = nm_ap_get_address (match_nofreq); const GByteArray *ap_ssid = nm_ap_get_ssid (match_nofreq); - nm_log_dbg (LOGD_WIFI, " matched %s%s%s %02x:%02x:%02x:%02x:%02x:%02x", - ap_ssid ? "'" : "", - ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", - ap_ssid ? "'" : "", - ap_bssid->ether_addr_octet[0], ap_bssid->ether_addr_octet[1], - ap_bssid->ether_addr_octet[2], ap_bssid->ether_addr_octet[3], - ap_bssid->ether_addr_octet[4], ap_bssid->ether_addr_octet[5]); + _LOGD (LOGD_WIFI, " matched %s%s%s %s", + ap_ssid ? "'" : "", + ap_ssid ? nm_utils_escape_ssid (ap_ssid->data, ap_ssid->len) : "(none)", + ap_ssid ? "'" : "", + str_if_set (nm_ap_get_address (match_nofreq), "(none)")); active_ap = match_nofreq; goto done; } - nm_log_dbg (LOGD_WIFI, " No matching AP found."); + _LOGD (LOGD_WIFI, " No matching AP found."); done: if (ssid) @@ -612,15 +589,17 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) * current AP with it, if the current AP is adhoc. */ if (priv->current_ap && (nm_ap_get_mode (priv->current_ap) == NM_802_11_MODE_ADHOC)) { - struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; + guint8 bssid[ETH_ALEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; - nm_platform_wifi_get_bssid (ifindex, &bssid); + nm_platform_wifi_get_bssid (ifindex, bssid); /* 0x02 means "locally administered" and should be OR-ed into * the first byte of IBSS BSSIDs. */ - if ( (bssid.ether_addr_octet[0] & 0x02) - && nm_ethernet_address_is_valid (&bssid)) - nm_ap_set_address (priv->current_ap, &bssid); + if ((bssid[0] & 0x02) && nm_ethernet_address_is_valid (bssid, ETH_ALEN)) { + char *bssid_str = nm_utils_hwaddr_ntoa (bssid, ETH_ALEN); + nm_ap_set_address (priv->current_ap, bssid_str); + g_free (bssid_str); + } } new_ap = find_active_ap (self, ignore_ap, FALSE); @@ -636,32 +615,26 @@ periodic_update (NMDeviceWifi *self, NMAccessPoint *ignore_ap) } if (new_ap != priv->current_ap) { - const struct ether_addr *new_bssid = NULL; + const char *new_bssid = NULL; const GByteArray *new_ssid = NULL; - const struct ether_addr *old_bssid = NULL; + const char *old_bssid = NULL; const GByteArray *old_ssid = NULL; - char *old_addr = NULL, *new_addr = NULL; if (new_ap) { new_bssid = nm_ap_get_address (new_ap); - new_addr = nm_utils_hwaddr_ntoa (new_bssid, ARPHRD_ETHER); new_ssid = nm_ap_get_ssid (new_ap); } if (priv->current_ap) { old_bssid = nm_ap_get_address (priv->current_ap); - old_addr = nm_utils_hwaddr_ntoa (old_bssid, ARPHRD_ETHER); old_ssid = nm_ap_get_ssid (priv->current_ap); } - nm_log_info (LOGD_WIFI, "(%s): roamed from BSSID %s (%s) to %s (%s)", - nm_device_get_iface (NM_DEVICE (self)), - old_addr ? old_addr : "(none)", - old_ssid ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)", - new_addr ? new_addr : "(none)", - new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)"); - g_free (old_addr); - g_free (new_addr); + _LOGI (LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", + old_bssid ? old_bssid : "(none)", + old_ssid ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)", + new_bssid ? new_bssid : "(none)", + new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)"); set_current_ap (self, new_ap, TRUE, FALSE); } @@ -734,15 +707,15 @@ remove_all_aps (NMDeviceWifi *self) } static void -deactivate (NMDevice *dev) +deactivate (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (dev); + int ifindex = nm_device_get_ifindex (device); NMConnection *connection; NM80211Mode old_mode = priv->mode; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); if (connection) { /* Clear wireless secrets tries when deactivating */ g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); @@ -768,7 +741,8 @@ deactivate (NMDevice *dev) nm_platform_wifi_indicate_addressing_running (ifindex, FALSE); /* Reset MAC address back to initial address */ - nm_device_set_hw_addr (dev, priv->initial_hw_addr, "reset", LOGD_WIFI); + if (priv->initial_hw_addr) + nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_WIFI); /* Ensure we're in infrastructure mode after deactivation; some devices * (usually older ones) don't scan well in adhoc mode. @@ -828,8 +802,9 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingConnection *s_con; NMSettingWireless *s_wireless; - const GByteArray *mac; - const GSList *mac_blacklist, *mac_blacklist_iter; + const char *mac; + const char * const *mac_blacklist; + int i; const char *mode; if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection)) @@ -846,21 +821,18 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, priv->perm_hw_addr, -1)) return FALSE; /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - for (mac_blacklist_iter = mac_blacklist; mac_blacklist_iter; - mac_blacklist_iter = g_slist_next (mac_blacklist_iter)) { - struct ether_addr addr; - - if (!ether_aton_r (mac_blacklist_iter->data, &addr)) { + for (i = 0; mac_blacklist[i]; i++) { + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { g_warn_if_reached (); - continue; + return FALSE; } - if (memcmp (&addr, &priv->perm_hw_addr, ETH_ALEN) == 0) + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, priv->perm_hw_addr, -1)) return FALSE; } @@ -998,10 +970,12 @@ complete_connection (NMDevice *device, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - const GByteArray *setting_mac; - char *format, *str_ssid = NULL; + const char *setting_mac; + char *str_ssid = NULL; NMAccessPoint *ap = NULL; const GByteArray *ssid = NULL; + GByteArray *tmp_ssid = NULL; + GBytes *setting_ssid = NULL; GSList *iter; gboolean hidden = FALSE; @@ -1013,17 +987,17 @@ complete_connection (NMDevice *device, /* If not given a specific object, we need at minimum an SSID */ if (!s_wifi) { g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wireless' setting is required if no AP path was given."); return FALSE; } - ssid = nm_setting_wireless_get_ssid (s_wifi); - if (!ssid || !ssid->len) { + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (!setting_ssid || g_bytes_get_size (setting_ssid) == 0) { g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wireless' setting with a valid SSID is required if no AP path was given."); return FALSE; } @@ -1041,17 +1015,7 @@ complete_connection (NMDevice *device, * if the network isn't broadcasting the SSID for example. */ if (!ap) { - GSList *settings = NULL; - gboolean valid; - - settings = g_slist_prepend (settings, s_wifi); - if (s_wsec) - settings = g_slist_prepend (settings, s_wsec); - if (s_8021x) - settings = g_slist_prepend (settings, s_8021x); - valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error); - g_slist_free (settings); - if (!valid) + if (!nm_setting_verify (NM_SETTING (s_wifi), connection, error)) return FALSE; hidden = TRUE; @@ -1060,8 +1024,8 @@ complete_connection (NMDevice *device, ap = get_ap_by_path (self, specific_object); if (!ap) { g_set_error (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "The access point %s was not in the scan list.", specific_object); return FALSE; @@ -1074,37 +1038,48 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wifi)); } - if (ap) { + if (ap) ssid = nm_ap_get_ssid (ap); - - if (ssid == NULL) { - /* The AP must be hidden. Connecting to a WiFi AP requires the SSID - * as part of the initial handshake, so check the connection details - * for the SSID. The AP object will still be used for encryption - * settings and such. - */ - ssid = nm_setting_wireless_get_ssid (s_wifi); + if (ssid == NULL) { + /* The AP must be hidden. Connecting to a WiFi AP requires the SSID + * as part of the initial handshake, so check the connection details + * for the SSID. The AP object will still be used for encryption + * settings and such. + */ + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (setting_ssid) { + ssid = tmp_ssid = g_byte_array_new (); + g_byte_array_append (tmp_ssid, + g_bytes_get_data (setting_ssid, NULL), + g_bytes_get_size (setting_ssid)); } + } - if (ssid == NULL) { - /* If there's no SSID on the AP itself, and no SSID in the - * connection data, then we cannot connect at all. Return an error. - */ - g_set_error_literal (error, - NM_WIFI_ERROR, - NM_WIFI_ERROR_CONNECTION_INVALID, - "A 'wireless' setting with a valid SSID is required for hidden access points."); - return FALSE; - } + if (ssid == NULL) { + /* If there's no SSID on the AP itself, and no SSID in the + * connection data, then we cannot connect at all. Return an error. + */ + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + ap + ? "A 'wireless' setting with a valid SSID is required for hidden access points." + : "Cannot create 'wireless' setting due to missing SSID."); + return FALSE; + } + if (ap) { /* If the SSID is a well-known SSID, lock the connection to the AP's * specific BSSID so NM doesn't autoconnect to some random wifi net. */ if (!nm_ap_complete_connection (ap, connection, is_manf_default_ssid (ssid), - error)) + error)) { + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; + } } /* The kernel doesn't support Ad-Hoc WPA connections well at this time, @@ -1113,24 +1088,27 @@ complete_connection (NMDevice *device, */ if (is_adhoc_wpa (connection)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc disabled due to kernel bugs"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA Ad-Hoc disabled due to kernel bugs")); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; } - g_assert (ssid); - str_ssid = nm_utils_ssid_to_utf8 (ssid); - format = g_strdup_printf ("%s %%d", str_ssid); + str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); nm_utils_complete_generic (connection, NM_SETTING_WIRELESS_SETTING_NAME, existing_connections, - format, str_ssid, + str_ssid, + NULL, TRUE); g_free (str_ssid); - g_free (format); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -1138,26 +1116,26 @@ complete_connection (NMDevice *device, setting_mac = nm_setting_wireless_get_mac_address (s_wifi); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { - g_set_error (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRELESS_MAC_ADDRESS); + if (!nm_utils_hwaddr_matches (setting_mac, -1, priv->perm_hw_addr, -1)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + guint8 perm_hw_addr[ETH_ALEN]; /* Lock the connection to this device by default if it uses a * permanent MAC address (ie not a 'locally administered' one) */ - if ( !(priv->perm_hw_addr[0] & 0x02) - && memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); + nm_utils_hwaddr_aton (priv->perm_hw_addr, perm_hw_addr, ETH_ALEN); + if ( !(perm_hw_addr[0] & 0x02) + && !nm_utils_hwaddr_matches (perm_hw_addr, ETH_ALEN, NULL, ETH_ALEN)) { + g_object_set (G_OBJECT (s_wifi), + NM_SETTING_WIRELESS_MAC_ADDRESS, priv->perm_hw_addr, + NULL); } } @@ -1165,31 +1143,26 @@ complete_connection (NMDevice *device, } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSupplicantInterface *sup_iface; guint32 state; if (!priv->enabled) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because not enabled", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because not enabled"); return FALSE; } - sup_iface = priv->sup_iface; - if (!sup_iface) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because supplicant not running", - nm_device_get_iface (dev)); + if (!priv->sup_iface) { + _LOGD (LOGD_WIFI, "not available because supplicant not running"); return FALSE; } - state = nm_supplicant_interface_get_state (sup_iface); + state = nm_supplicant_interface_get_state (priv->sup_iface); if ( state < NM_SUPPLICANT_INTERFACE_STATE_READY || state > NM_SUPPLICANT_INTERFACE_STATE_COMPLETED) { - nm_log_dbg (LOGD_WIFI, "(%s): not available because supplicant interface not ready", - nm_device_get_iface (dev)); + _LOGD (LOGD_WIFI, "not available because supplicant interface not ready"); return FALSE; } @@ -1197,17 +1170,17 @@ is_available (NMDevice *dev) } static gboolean -can_auto_connect (NMDevice *dev, +can_auto_connect (NMDevice *device, NMConnection *connection, char **specific_object) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); GSList *ap_iter; const char *method = NULL; guint64 timestamp = 0; - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (dev, connection, specific_object)) + if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (device, connection, specific_object)) return FALSE; /* Don't autoconnect to networks that have been tried at least once @@ -1246,12 +1219,12 @@ ap_list_dump (NMDeviceWifi *self) g_return_if_fail (NM_IS_DEVICE_WIFI (self)); - nm_log_dbg (LOGD_WIFI_SCAN, "Current AP list:"); + _LOGD (LOGD_WIFI_SCAN, "Current AP list:"); for (elt = priv->ap_list; elt; elt = g_slist_next (elt), i++) { NMAccessPoint * ap = NM_AP (elt->data); nm_ap_dump (ap, "List AP: "); } - nm_log_dbg (LOGD_WIFI_SCAN, "Current AP list: done"); + _LOGD (LOGD_WIFI_SCAN, "Current AP list: done"); } static gboolean @@ -1301,8 +1274,8 @@ request_scan_cb (NMDevice *device, } if (!check_scanning_allowed (self)) { - local = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + local = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed at this time"); dbus_g_method_return_error (context, local); g_error_free (local); @@ -1328,23 +1301,23 @@ impl_device_request_scan (NMDeviceWifi *self, || !priv->sup_iface || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED || nm_device_is_activating (device)) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while unavailable or activating"); goto error; } if (nm_supplicant_interface_get_scanning (priv->sup_iface)) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while already scanning"); goto error; } last_scan = nm_supplicant_interface_get_last_scan_time (priv->sup_iface); if (last_scan && (nm_utils_get_monotonic_timestamp_s () - last_scan) < 10) { - error = g_error_new_literal (NM_WIFI_ERROR, - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed immediately following previous scan"); goto error; } @@ -1413,7 +1386,6 @@ scanning_allowed (NMDeviceWifi *self) if (connection) { NMSettingWireless *s_wifi; const char *ip4_method = NULL; - const GByteArray *bssid; /* Don't scan when a shared connection is active; it makes drivers mad */ ip4_method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); @@ -1427,8 +1399,7 @@ scanning_allowed (NMDeviceWifi *self) */ s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - bssid = nm_setting_wireless_get_bssid (s_wifi); - if (bssid && bssid->len == ETH_ALEN) + if (nm_setting_wireless_get_bssid (s_wifi)) return FALSE; } @@ -1500,20 +1471,25 @@ build_hidden_probe_list (NMDeviceWifi *self) hidden_filter_func, NULL); if (connections && connections->data) { - ssids = g_ptr_array_sized_new (max_scan_ssids - 1); - g_ptr_array_add (ssids, nullssid); /* Add wildcard SSID */ + 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 */ } for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *connection = iter->data; NMSettingWireless *s_wifi; - const GByteArray *ssid; + GBytes *ssid; + GByteArray *ssid_array; s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (connection); g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); g_assert (ssid); - g_ptr_array_add (ssids, (gpointer) ssid); + ssid_array = g_byte_array_new (); + g_byte_array_append (ssid_array, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + g_ptr_array_add (ssids, ssid_array); } g_slist_free (connections); @@ -1534,27 +1510,25 @@ request_wireless_scan (gpointer user_data) } if (check_scanning_allowed (self)) { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scanning requested", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_WIFI_SCAN, "scanning requested"); ssids = build_hidden_probe_list (self); if (nm_logging_enabled (LOGL_DEBUG, LOGD_WIFI_SCAN)) { if (ssids) { + const GByteArray *ssid; guint i; char *foo; for (i = 0; i < ssids->len; i++) { - foo = nm_utils_ssid_to_utf8 (g_ptr_array_index (ssids, i)); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): (%d) probe scanning SSID '%s'", - nm_device_get_iface (NM_DEVICE (self)), + ssid = g_ptr_array_index (ssids, i); + foo = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); + _LOGD (LOGD_WIFI_SCAN, "(%d) probe scanning SSID '%s'", i, foo ? foo : ""); g_free (foo); } - } else { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): no SSIDs to probe scan", - nm_device_get_iface (NM_DEVICE (self))); - } + } else + _LOGD (LOGD_WIFI_SCAN, "no SSIDs to probe scan"); } if (nm_supplicant_interface_request_scan (priv->sup_iface, ssids)) { @@ -1564,14 +1538,10 @@ request_wireless_scan (gpointer user_data) nm_device_add_pending_action (NM_DEVICE (self), "scan", TRUE); } - if (ssids) { - /* Elements owned by the connections, so we don't free them here */ - g_ptr_array_free (ssids, TRUE); - } - } else { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan requested but not allowed at this time", - nm_device_get_iface (NM_DEVICE (self))); - } + if (ssids) + g_ptr_array_unref (ssids); + } else + _LOGD (LOGD_WIFI_SCAN, "scan requested but not allowed at this time"); priv->pending_scan_id = 0; schedule_scan (self, backoff); @@ -1622,11 +1592,8 @@ schedule_scan (NMDeviceWifi *self, gboolean backoff) priv->scan_interval = 5; } - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scheduled scan in %d seconds (interval now %d seconds)", - nm_device_get_iface (NM_DEVICE (self)), - next_scan, - priv->scan_interval); - + _LOGD (LOGD_WIFI_SCAN, "scheduled scan in %d seconds (interval now %d seconds)", + next_scan, priv->scan_interval); } } @@ -1649,9 +1616,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan %s", - nm_device_get_iface (NM_DEVICE (self)), - success ? "successful" : "failed"); + _LOGD (LOGD_WIFI_SCAN, "scan %s", success ? "successful" : "failed"); schedule_scan (self, success); @@ -1674,7 +1639,7 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, static void try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) { - const struct ether_addr *bssid; + const char *bssid; const GSList *connections, *iter; g_return_if_fail (nm_ap_get_ssid (ap) == NULL); @@ -1692,16 +1657,17 @@ try_fill_ssid_for_hidden_ap (NMAccessPoint *ap) s_wifi = nm_connection_get_setting_wireless (connection); if (s_wifi) { if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid)) { - nm_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + GBytes *ssid = nm_setting_wireless_get_ssid (s_wifi); + + nm_ap_set_ssid (ap, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); break; } } } } -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] - /* * merge_scanned_ap * @@ -1721,7 +1687,7 @@ merge_scanned_ap (NMDeviceWifi *self, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMAccessPoint *found_ap = NULL; const GByteArray *ssid; - const struct ether_addr *bssid; + const char *bssid; gboolean strict_match = TRUE; /* Let the manager try to fill in the SSID from seen-bssids lists */ @@ -1734,16 +1700,13 @@ merge_scanned_ap (NMDeviceWifi *self, ssid = nm_ap_get_ssid (merge_ap); if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { /* Yay, matched it, no longer treat as hidden */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): matched hidden AP " MAC_FMT " => '%s'", - nm_device_get_iface (NM_DEVICE (self)), - MAC_ARG (bssid->ether_addr_octet), - nm_utils_escape_ssid (ssid->data, ssid->len)); + _LOGD (LOGD_WIFI_SCAN, "matched hidden AP %s => '%s'", + str_if_set (bssid, "(none)"), nm_utils_escape_ssid (ssid->data, ssid->len)); nm_ap_set_broadcast (merge_ap, FALSE); } else { /* Didn't have an entry for this AP in the database */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): failed to match hidden AP " MAC_FMT, - nm_device_get_iface (NM_DEVICE (self)), - MAC_ARG (bssid->ether_addr_octet)); + _LOGD (LOGD_WIFI_SCAN, "failed to match hidden AP %s", + str_if_set (bssid, "(none)")); } } @@ -1760,10 +1723,9 @@ merge_scanned_ap (NMDeviceWifi *self, if (!found_ap) found_ap = nm_ap_match_in_list (merge_ap, priv->ap_list, strict_match); if (found_ap) { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): merging AP '%s' " MAC_FMT " (%p) with existing (%p)", - nm_device_get_iface (NM_DEVICE (self)), + _LOGD (LOGD_WIFI_SCAN, "merging AP '%s' %s (%p) with existing (%p)", ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - MAC_ARG (bssid->ether_addr_octet), + str_if_set (bssid, "(none)"), merge_ap, found_ap); @@ -1783,11 +1745,9 @@ merge_scanned_ap (NMDeviceWifi *self, nm_ap_set_fake (found_ap, FALSE); } else { /* New entry in the list */ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): adding new AP '%s' " MAC_FMT " (%p)", - nm_device_get_iface (NM_DEVICE (self)), - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - MAC_ARG (bssid->ether_addr_octet), - merge_ap); + _LOGD (LOGD_WIFI_SCAN, "adding new AP '%s' %s (%p)", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + str_if_set (bssid, "(none)"), merge_ap); g_object_ref (merge_ap); priv->ap_list = g_slist_prepend (priv->ap_list, merge_ap); @@ -1809,8 +1769,7 @@ cull_scan_list (NMDeviceWifi *self) priv->scanlist_cull_id = 0; - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): checking scan list for outdated APs", - nm_device_get_iface (NM_DEVICE (self))); + _LOGD (LOGD_WIFI_SCAN, "checking scan list for outdated APs"); /* Walk the access point list and remove any access points older than * three times the inactive scan interval. @@ -1844,28 +1803,23 @@ cull_scan_list (NMDeviceWifi *self) /* Remove outdated APs */ for (elt = outdated_list; elt; elt = g_slist_next (elt)) { NMAccessPoint *outdated_ap = NM_AP (elt->data); - const struct ether_addr *bssid; const GByteArray *ssid; - bssid = nm_ap_get_address (outdated_ap); ssid = nm_ap_get_ssid (outdated_ap); - nm_log_dbg (LOGD_WIFI_SCAN, - " removing %02x:%02x:%02x:%02x:%02x:%02x (%s%s%s)", - bssid->ether_addr_octet[0], bssid->ether_addr_octet[1], - bssid->ether_addr_octet[2], bssid->ether_addr_octet[3], - bssid->ether_addr_octet[4], bssid->ether_addr_octet[5], - ssid ? "'" : "", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", - ssid ? "'" : ""); + _LOGD (LOGD_WIFI_SCAN, + " removing %s (%s%s%s)", + str_if_set (nm_ap_get_address (outdated_ap), "(none)"), + ssid ? "'" : "", + ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)", + ssid ? "'" : ""); remove_access_point (self, outdated_ap); removed++; } g_slist_free (outdated_list); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): removed %d APs (of %d)", - nm_device_get_iface (NM_DEVICE (self)), - removed, total); + _LOGD (LOGD_WIFI_SCAN, "removed %d APs (of %d)", + removed, total); ap_list_dump (self); @@ -1913,10 +1867,8 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, /* Add the AP to the device's AP list */ merge_scanned_ap (self, ap); g_object_unref (ap); - } else { - nm_log_warn (LOGD_WIFI_SCAN, "(%s): invalid AP properties received", - nm_device_get_iface (NM_DEVICE (self))); - } + } else + _LOGW (LOGD_WIFI_SCAN, "invalid AP properties received"); /* Remove outdated access points */ schedule_scanlist_cull (self); @@ -1998,19 +1950,20 @@ wifi_secrets_cb (NMActRequest *req, GError *error, gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); - g_return_if_fail (req == nm_device_get_act_request (dev)); - g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail (req == nm_device_get_act_request (device)); + g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); g_return_if_fail (nm_act_request_get_connection (req) == connection); if (error) { - nm_log_warn (LOGD_WIFI, "%s", error->message); - nm_device_state_changed (dev, + _LOGW (LOGD_WIFI, "%s", error->message); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); } else - nm_device_activate_schedule_stage1_device_prepare (dev); + nm_device_activate_schedule_stage1_device_prepare (device); } /* @@ -2022,11 +1975,11 @@ wifi_secrets_cb (NMActRequest *req, static gboolean link_timeout_cb (gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDevice *device = NM_DEVICE (user_data); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_log_warn (LOGD_WIFI, "(%s): link timed out.", nm_device_get_iface (dev)); + _LOGW (LOGD_WIFI, "link timed out."); priv->link_timeout_id = 0; @@ -2034,7 +1987,7 @@ link_timeout_cb (gpointer user_data) * to reassociate within the timeout period, so the connection must * fail. */ - if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED) + if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) return FALSE; /* If the access point failed, and wasn't found by the supplicant when it @@ -2045,7 +1998,7 @@ link_timeout_cb (gpointer user_data) if (priv->ssid_found == FALSE && priv->current_ap) set_current_ap (self, NULL, TRUE, TRUE); - nm_device_state_changed (dev, + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); @@ -2080,10 +2033,11 @@ need_new_8021x_secrets (NMDeviceWifi *self, s_8021x = nm_connection_get_setting_802_1x (connection); if (s_8021x) { - nm_setting_get_secret_flags (NM_SETTING (s_8021x), - NM_SETTING_802_1X_PASSWORD, - &secret_flags, - NULL); + if (!nm_setting_get_secret_flags (NM_SETTING (s_8021x), + NM_SETTING_802_1X_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached (); if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) *setting_name = NM_SETTING_802_1X_SETTING_NAME; return *setting_name ? TRUE : FALSE; @@ -2091,10 +2045,11 @@ need_new_8021x_secrets (NMDeviceWifi *self, s_wsec = nm_connection_get_setting_wireless_security (connection); if (s_wsec) { - nm_setting_get_secret_flags (NM_SETTING (s_wsec), - NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, - &secret_flags, - NULL); + if (!nm_setting_get_secret_flags (NM_SETTING (s_wsec), + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, + &secret_flags, + NULL)) + g_assert_not_reached (); if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; return *setting_name ? TRUE : FALSE; @@ -2160,16 +2115,15 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): disconnected during association," - " asking for new key.", nm_device_get_iface (device)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) disconnected during association, asking for new key"); cleanup_association_attempt (self, TRUE); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION - | NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION + | NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wifi_secrets_cb, self); @@ -2195,11 +2149,10 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (new_state == old_state) return; - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "(%s): supplicant interface state: %s -> %s", - nm_device_get_iface (device), - nm_supplicant_interface_state_to_string (old_state), - nm_supplicant_interface_state_to_string (new_state)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "supplicant interface state: %s -> %s", + nm_supplicant_interface_state_to_string (old_state), + nm_supplicant_interface_state_to_string (new_state)); devstate = nm_device_get_state (device); scanning = nm_supplicant_interface_get_scanning (iface); @@ -2222,9 +2175,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE); } - nm_log_dbg (LOGD_WIFI_SCAN, - "(%s): supplicant ready, requesting initial scan", - nm_device_get_iface (device)); + _LOGD (LOGD_WIFI_SCAN, "supplicant ready, requesting initial scan"); /* Request a scan to get latest results */ cancel_pending_scan (self); @@ -2243,7 +2194,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, if (devstate == NM_DEVICE_STATE_CONFIG) { NMConnection *connection; NMSettingWireless *s_wifi; - const GByteArray *ssid; + GBytes *ssid; connection = nm_device_get_connection (NM_DEVICE (self)); g_return_if_fail (connection); @@ -2254,13 +2205,12 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, ssid = nm_setting_wireless_get_ssid (s_wifi); g_return_if_fail (ssid); - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless) Stage 2 of 5 (Device Configure) " - "successful. %s '%s'.", - nm_device_get_iface (device), - priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" : - "Connected to wireless network", - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)"); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s '%s'.", + priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" : + "Connected to wireless network", + ssid ? nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)) : "(none)"); nm_device_activate_schedule_stage3_ip_config_start (device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update (self, NULL); @@ -2326,9 +2276,9 @@ supplicant_iface_connection_error_cb (NMSupplicantInterface *iface, NMDevice *device = NM_DEVICE (self); if (nm_device_is_activating (device)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): supplicant association failed: %s - %s", - nm_device_get_iface (device), name, message); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) supplicant association failed: %s - %s", + name, message); cleanup_association_attempt (self, TRUE); nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); @@ -2356,9 +2306,7 @@ supplicant_iface_notify_scanning_cb (NMSupplicantInterface *iface, gboolean scanning; scanning = nm_supplicant_interface_get_scanning (iface); - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): now %s", - nm_device_get_iface (NM_DEVICE (self)), - scanning ? "scanning" : "idle"); + _LOGD (LOGD_WIFI_SCAN, "now %s", scanning ? "scanning" : "idle"); g_object_notify (G_OBJECT (self), "scanning"); @@ -2397,16 +2345,16 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (new_secrets) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else - nm_log_warn (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); + _LOGW (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); return ret; } @@ -2420,7 +2368,7 @@ handle_auth_or_fail (NMDeviceWifi *self, static gboolean supplicant_connection_timeout_cb (gpointer user_data) { - NMDevice *dev = NM_DEVICE (user_data); + NMDevice *device = NM_DEVICE (user_data); NMDeviceWifi *self = NM_DEVICE_WIFI (user_data); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActRequest *req; @@ -2428,7 +2376,7 @@ supplicant_connection_timeout_cb (gpointer user_data) cleanup_association_attempt (self, TRUE); - if (!nm_device_is_activating (dev)) + if (!nm_device_is_activating (device)) return FALSE; /* Timed out waiting for a successful connection to the AP; if the AP's @@ -2437,7 +2385,7 @@ supplicant_connection_timeout_cb (gpointer user_data) * information (passwords, pin codes, etc) are wrong. */ - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); connection = nm_act_request_get_connection (req); @@ -2449,12 +2397,10 @@ supplicant_connection_timeout_cb (gpointer user_data) * (if any), so supplicant timeouts here are almost certainly the wifi * driver being really stupid. */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): %s network creation took " - "too long, failing activation.", - nm_device_get_iface (dev), - priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) %s network creation took too long, failing activation", + priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); return FALSE; } @@ -2468,9 +2414,8 @@ supplicant_connection_timeout_cb (gpointer user_data) /* Connection failed; either driver problems, the encryption key is * wrong, or the passwords or certificates were wrong. */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): association took too long.", - nm_device_get_iface (dev)); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) association took too long"); /* Ask for new secrets only if we've never activated this connection * before. If we've connected before, don't bother the user with @@ -2480,20 +2425,16 @@ supplicant_connection_timeout_cb (gpointer user_data) if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) new_secrets = !timestamp; - if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): asking for new secrets", - nm_device_get_iface (dev)); - } else { - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + if (handle_auth_or_fail (self, req, new_secrets) == NM_ACT_STAGE_RETURN_POSTPONE) + _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) asking for new secrets"); + else { + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); } } else { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): association took too long, " - "failing activation.", - nm_device_get_iface (dev)); - nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) association took too long, failing activation"); + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, priv->ssid_found ? NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : NM_DEVICE_STATE_REASON_SSID_NOT_FOUND); } @@ -2523,13 +2464,13 @@ build_supplicant_config (NMDeviceWifi *self, /* Warn if AP mode may not be supported */ if ( g_strcmp0 (nm_setting_wireless_get_mode (s_wireless), NM_SETTING_WIRELESS_MODE_AP) == 0 && nm_supplicant_interface_get_ap_support (priv->sup_iface) == AP_SUPPORT_UNKNOWN) { - nm_log_warn (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); + _LOGW (LOGD_WIFI, "Supplicant may not support AP mode; connection may time out."); } if (!nm_supplicant_config_add_setting_wireless (config, s_wireless, fixed_freq)) { - nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless setting to supplicant config."); goto error; } @@ -2544,13 +2485,12 @@ build_supplicant_config (NMDeviceWifi *self, s_wireless_sec, s_8021x, con_uuid)) { - nm_log_err (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to " - "supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add 802-11-wireless-security setting to supplicant config."); goto error; } } else { if (!nm_supplicant_config_add_no_security (config)) { - nm_log_err (LOGD_WIFI, "Couldn't add unsecured option to supplicant config."); + _LOGE (LOGD_WIFI, "Couldn't add unsecured option to supplicant config."); goto error; } } @@ -2565,23 +2505,25 @@ error: /****************************************************************************/ static void -update_permanent_hw_address (NMDevice *dev) +update_permanent_hw_address (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); struct ifreq req; struct ethtool_perm_addr *epaddr = NULL; - int fd, ret; + int fd, ret, errsv; + + g_return_if_fail (priv->perm_hw_addr == NULL); fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_err (LOGD_HW, "could not open control socket."); + _LOGE (LOGD_HW, "could not open control socket."); return; } /* Get permanent MAC address */ memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); + strncpy (req.ifr_name, nm_device_get_iface (device), IFNAMSIZ); epaddr = g_malloc0 (sizeof (struct ethtool_perm_addr) + ETH_ALEN); epaddr->cmd = ETHTOOL_GPERMADDR; @@ -2590,56 +2532,50 @@ update_permanent_hw_address (NMDevice *dev) errno = 0; ret = ioctl (fd, SIOCETHTOOL, &req); - if ((ret < 0) || !nm_ethernet_address_is_valid ((struct ether_addr *) epaddr->data)) { - nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", - nm_device_get_iface (dev), errno); + errsv = errno; + if ((ret < 0) || !nm_ethernet_address_is_valid (epaddr->data, ETH_ALEN)) { + _LOGD (LOGD_HW | LOGD_ETHER, "unable to read permanent MAC address (error %d)", + errsv); /* Fall back to current address */ - memcpy (epaddr->data, nm_device_get_hw_address (dev, NULL), ETH_ALEN); + nm_utils_hwaddr_aton (nm_device_get_hw_address (device), epaddr->data, ETH_ALEN); } - if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { - memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN); - g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); - } + priv->perm_hw_addr = nm_utils_hwaddr_ntoa (epaddr->data, ETH_ALEN); g_free (epaddr); close (fd); } static void -update_initial_hw_address (NMDevice *dev) +update_initial_hw_address (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - char *mac_str; /* This sets initial MAC address from current MAC address. It should only * be called from NMDevice constructor() to really get the initial address. */ - memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); + priv->initial_hw_addr = g_strdup (nm_device_get_hw_address (device)); - mac_str = nm_utils_hwaddr_ntoa (priv->initial_hw_addr, ARPHRD_ETHER); - nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): read initial MAC address %s", - nm_device_get_iface (dev), mac_str); - g_free (mac_str); + _LOGD (LOGD_DEVICE | LOGD_ETHER, "read initial MAC address %s", priv->initial_hw_addr); } static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActStageReturn ret; NMAccessPoint *ap = NULL; NMActRequest *req; NMConnection *connection; NMSettingWireless *s_wireless; - const GByteArray *cloned_mac; + const char *cloned_mac; GSList *iter; const char *mode; const char *ap_path; - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage1_prepare (device, reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; @@ -2670,15 +2606,15 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) * 2.6.30 or so; until that's fixed, disable WPA-protected Ad-Hoc networks. */ if (is_adhoc_wpa (connection)) { - nm_log_warn (LOGD_WIFI, "Ad-Hoc WPA disabled due to kernel bugs"); + _LOGW (LOGD_WIFI, "Ad-Hoc WPA disabled due to kernel bugs"); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } /* Set spoof MAC to the interface */ cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); - if (cloned_mac && (cloned_mac->len == ETH_ALEN)) - nm_device_set_hw_addr (dev, (const guint8 *) cloned_mac->data, "set", LOGD_WIFI); + if (cloned_mac) + nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_WIFI); /* AP mode never uses a specific object or existing scanned AP */ if (priv->mode != NM_802_11_MODE_AP) { @@ -2716,7 +2652,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) nm_ap_set_broadcast (ap, FALSE); else if (nm_ap_is_hotspot (ap)) - nm_ap_set_address (ap, (const struct ether_addr *) nm_device_get_hw_address (dev, NULL)); + nm_ap_set_address (ap, nm_device_get_hw_address (device)); priv->ap_list = g_slist_prepend (priv->ap_list, ap); nm_ap_export_to_dbus (ap); @@ -2759,12 +2695,11 @@ ensure_hotspot_frequency (NMDeviceWifi *self, } static NMActStageReturn -act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) +act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - const char *iface = nm_device_get_iface (dev); NMSupplicantConfig *config = NULL; NMActRequest *req; NMAccessPoint *ap; @@ -2776,7 +2711,7 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) remove_supplicant_timeouts (self); - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); ap = priv->current_ap; @@ -2794,10 +2729,9 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): access point '%s' has security," - " but secrets are required.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) access point '%s' has security, but secrets are required.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, req, FALSE); if (ret == NM_ACT_STAGE_RETURN_FAILURE) @@ -2807,15 +2741,13 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* have secrets, or no secrets required */ if (nm_connection_get_setting_wireless_security (connection)) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): connection '%s' has security" - ", and secrets exist. No new secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' has security, and secrets exist. No new secrets needed.", + nm_connection_get_id (connection)); } else { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): connection '%s' requires no " - "security. No secrets needed.", - iface, nm_connection_get_id (connection)); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) connection '%s' requires no security. No secrets needed.", + nm_connection_get_id (connection)); } priv->ssid_found = FALSE; @@ -2830,9 +2762,8 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* Build up the supplicant configuration */ config = build_supplicant_config (self, connection, nm_ap_get_freq (ap)); if (config == NULL) { - nm_log_err (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): couldn't build wireless configuration.", - iface); + _LOGE (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) couldn't build wireless configuration."); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; goto out; } @@ -2844,9 +2775,8 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) self); if (!nm_supplicant_interface_set_config (priv->sup_iface, config)) { - nm_log_err (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): couldn't send wireless " - "configuration to the supplicant.", iface); + _LOGE (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) couldn't send wireless configuration to the supplicant."); *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED; goto out; } @@ -2879,14 +2809,14 @@ act_stage3_ip4_config_start (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; const char *method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; connection = nm_device_get_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); /* Indicate that a critical protocol is about to start */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) @@ -2901,14 +2831,14 @@ act_stage3_ip6_config_start (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; const char *method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; connection = nm_device_get_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) - method = nm_setting_ip6_config_get_method (s_ip6); + method = nm_setting_ip_config_get_method (s_ip6); /* Indicate that a critical protocol is about to start */ if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 || @@ -2933,7 +2863,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) /* MTU override */ mtu = nm_setting_wireless_get_mtu (s_wifi); if (mtu) - nm_ip4_config_set_mtu (config, mtu); + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); } static gboolean @@ -2984,17 +2914,14 @@ handle_ip_config_timeout (NMDeviceWifi *self, */ if (!may_fail && is_static_wep (connection)) { /* Activation failed, we must have bad encryption key */ - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): could not get IP configuration for " - "connection '%s'.", - nm_device_get_iface (NM_DEVICE (self)), - nm_connection_get_id (connection)); + _LOGW (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) could not get IP configuration for connection '%s'.", + nm_connection_get_id (connection)); ret = handle_auth_or_fail (self, NULL, TRUE); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { - nm_log_info (LOGD_DEVICE | LOGD_WIFI, - "Activation (%s/wireless): asking for new secrets", - nm_device_get_iface (NM_DEVICE (self))); + _LOGI (LOGD_DEVICE | LOGD_WIFI, + "Activation: (wifi) asking for new secrets"); } else { *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } @@ -3008,60 +2935,60 @@ handle_ip_config_timeout (NMDeviceWifi *self, static NMActStageReturn -act_stage4_ip4_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) +act_stage4_ip4_config_timeout (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); - may_fail = nm_setting_ip4_config_get_may_fail (s_ip4); + may_fail = nm_setting_ip_config_get_may_fail (s_ip4); - ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); + ret = handle_ip_config_timeout (NM_DEVICE_WIFI (device), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (device, reason); return ret; } static NMActStageReturn -act_stage4_ip6_config_timeout (NMDevice *dev, NMDeviceStateReason *reason) +act_stage4_ip6_config_timeout (NMDevice *device, NMDeviceStateReason *reason) { NMConnection *connection; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); - may_fail = nm_setting_ip6_config_get_may_fail (s_ip6); + may_fail = nm_setting_ip_config_get_may_fail (s_ip6); - ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason); + ret = handle_ip_config_timeout (NM_DEVICE_WIFI (device), connection, may_fail, &chain_up, reason); if (chain_up) - ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, reason); + ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (device, reason); return ret; } static void -activation_success_handler (NMDevice *dev) +activation_success_handler (NMDevice *device) { - NMDeviceWifi *self = NM_DEVICE_WIFI (dev); + NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int ifindex = nm_device_get_ifindex (dev); + int ifindex = nm_device_get_ifindex (device); NMAccessPoint *ap; - struct ether_addr bssid = { {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} }; + guint8 bssid[ETH_ALEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; NMAccessPoint *tmp_ap = NULL; NMActRequest *req; NMConnection *connection; - req = nm_device_get_act_request (dev); + req = nm_device_get_act_request (device); g_assert (req); connection = nm_act_request_get_connection (req); @@ -3087,9 +3014,12 @@ activation_success_handler (NMDevice *dev) * But if activation was successful, the card will know the BSSID. Grab * the BSSID off the card and fill in the BSSID of the activation AP. */ - nm_platform_wifi_get_bssid (ifindex, &bssid); - if (!nm_ethernet_address_is_valid (nm_ap_get_address (ap))) - nm_ap_set_address (ap, &bssid); + nm_platform_wifi_get_bssid (ifindex, bssid); + if (!nm_ap_get_address (ap)) { + char *bssid_str = nm_utils_hwaddr_ntoa (bssid, ETH_ALEN); + nm_ap_set_address (ap, bssid_str); + g_free (bssid_str); + } if (!nm_ap_get_freq (ap)) nm_ap_set_freq (ap, nm_platform_wifi_get_frequency (ifindex)); if (!nm_ap_get_max_bitrate (ap)) @@ -3103,9 +3033,11 @@ activation_success_handler (NMDevice *dev) * instead. */ - /* If the better match was a hidden AP, update it's SSID */ - if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) - nm_ap_set_ssid (tmp_ap, nm_ap_get_ssid (ap)); + /* If the better match was a hidden AP, update its SSID */ + if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len)) { + ssid = nm_ap_get_ssid (ap); + nm_ap_set_ssid (tmp_ap, ssid->data, ssid->len); + } nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_ap_get_dbus_path (tmp_ap)); @@ -3130,18 +3062,18 @@ done: } static void -activation_failure_handler (NMDevice *dev) +activation_failure_handler (NMDevice *device) { NMConnection *connection; - connection = nm_device_get_connection (dev); + connection = nm_device_get_connection (device); g_assert (connection); /* Clear wireless secrets tries on failure */ g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); /* Clear any critical protocol notification in the wifi stack */ - nm_platform_wifi_indicate_addressing_running (nm_device_get_ifindex (dev), FALSE); + nm_platform_wifi_indicate_addressing_running (nm_device_get_ifindex (device), FALSE); } static void @@ -3225,15 +3157,12 @@ set_enabled (NMDevice *device, gboolean enabled) priv->enabled = enabled; - nm_log_dbg (LOGD_WIFI, "(%s): device now %s", - nm_device_get_iface (NM_DEVICE (device)), - enabled ? "enabled" : "disabled"); + _LOGD (LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled"); state = nm_device_get_state (NM_DEVICE (self)); if (state < NM_DEVICE_STATE_UNAVAILABLE) { - nm_log_dbg (LOGD_WIFI, "(%s): %s blocked by UNMANAGED state", - enabled ? "enable" : "disable", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "(%s): device blocked by UNMANAGED state", + enabled ? "enable" : "disable"); return; } @@ -3241,11 +3170,10 @@ set_enabled (NMDevice *device, gboolean enabled) gboolean no_firmware = FALSE; if (state != NM_DEVICE_STATE_UNAVAILABLE) - nm_log_warn (LOGD_CORE, "not in expected unavailable state!"); + _LOGW (LOGD_CORE, "not in expected unavailable state!"); if (!nm_device_bring_up (NM_DEVICE (self), TRUE, &no_firmware)) { - nm_log_dbg (LOGD_WIFI, "(%s): enable blocked by failure to bring device up", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "enable blocked by failure to bring device up"); if (no_firmware) nm_device_set_firmware_missing (NM_DEVICE (device), TRUE); @@ -3261,8 +3189,7 @@ set_enabled (NMDevice *device, gboolean enabled) supplicant_interface_release (self); supplicant_interface_acquire (self); - nm_log_dbg (LOGD_WIFI, "(%s): enable waiting on supplicant state", - nm_device_get_iface (NM_DEVICE (device))); + _LOGD (LOGD_WIFI, "enable waiting on supplicant state"); } else { nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, @@ -3320,6 +3247,18 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object); } +static void +finalize (GObject *object) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (object); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + + g_free (priv->perm_hw_addr); + g_free (priv->initial_hw_addr); + + G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -3331,7 +3270,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); + g_value_set_string (value, priv->perm_hw_addr); break; case PROP_MODE: g_value_set_uint (value, priv->mode); @@ -3387,6 +3326,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; + object_class->finalize = finalize; parent_class->bring_up = bring_up; parent_class->update_permanent_hw_address = update_permanent_hw_address; @@ -3413,57 +3353,56 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) klass->scanning_allowed = scanning_allowed; /* Properties */ - g_object_class_install_property (object_class, PROP_PERM_HW_ADDRESS, - g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, - "Permanent MAC Address", - "Permanent hardware MAC address", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_DEVICE_WIFI_MODE, - "Mode", - "Mode", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_BITRATE, - g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, - "Bitrate", - "Bitrate", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_PERM_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_uint (NM_DEVICE_WIFI_MODE, "", "", + NM_802_11_MODE_UNKNOWN, + NM_802_11_MODE_AP, + NM_802_11_MODE_INFRA, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_BITRATE, + g_param_spec_uint (NM_DEVICE_WIFI_BITRATE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACCESS_POINTS, - g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, - "Access points", - "Access points", + g_param_spec_boxed (NM_DEVICE_WIFI_ACCESS_POINTS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_ACTIVE_ACCESS_POINT, - g_param_spec_boxed (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, - "Active access point", - "Currently active access point", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, - "Wireless Capabilities", - "Wireless Capabilities", - 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_SCANNING, - g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, - "Scanning", - "Scanning", - FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_ACCESS_POINT, + g_param_spec_boxed (NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_WIFI_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_SCANNING, + g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[ACCESS_POINT_ADDED] = @@ -3495,8 +3434,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_wifi_object_info); - - dbus_g_error_domain_register (NM_WIFI_ERROR, NULL, NM_TYPE_WIFI_ERROR); } diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index f0a1beac..bcba91da 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -19,12 +19,10 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DEVICE_WIFI_H -#define NM_DEVICE_WIFI_H +#ifndef __NETWORKMANAGER_DEVICE_WIFI_H__ +#define __NETWORKMANAGER_DEVICE_WIFI_H__ #include -#include -#include #include "nm-device.h" #include "nm-wifi-ap.h" @@ -40,16 +38,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIFI)) #define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass)) -typedef enum { - NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, /*< nick=ConnectionNotWireless >*/ - NM_WIFI_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, /*< nick=AccessPointNotFound >*/ - NM_WIFI_ERROR_SCAN_NOT_ALLOWED, /*< nick=ScanNotAllowed >*/ - NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, /*< nick=ApModeUnsupported >*/ - NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, /*< nick=AdhocModeUnsupported >*/ -} NMWifiError; - #define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address" #define NM_DEVICE_WIFI_MODE "mode" #define NM_DEVICE_WIFI_BITRATE "bitrate" diff --git a/src/devices/wifi/nm-wifi-ap-utils.c b/src/devices/wifi/nm-wifi-ap-utils.c index 9b03cbd4..9ac7052e 100644 --- a/src/devices/wifi/nm-wifi-ap-utils.c +++ b/src/devices/wifi/nm-wifi-ap-utils.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*-*- 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 @@ -18,11 +18,15 @@ * (C) Copyright 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include +#include + #include "nm-wifi-ap-utils.h" +#include "nm-utils.h" static gboolean verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -35,9 +39,10 @@ verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **erro || nm_setting_wireless_security_get_wep_key_type (s_wsec)) { /* Dynamic WEP cannot have any WEP keys set */ g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with static WEP keys", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("%s is incompatible with static WEP keys"), tag); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; } @@ -68,17 +73,21 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, /* LEAP authentication requires at least a LEAP username */ if (!leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, - "LEAP requires a LEAP username"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("LEAP authentication requires a LEAP username")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); return FALSE; } } else if (leap_username) { /* Leap username requires 'leap' auth */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "LEAP requires 'leap' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP username requires 'leap' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); return FALSE; } } @@ -87,9 +96,11 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) { /* LEAP requires ieee8021x key management */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, - "LEAP requires IEEE 802.1x key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("LEAP authentication requires IEEE 802.1x key management")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -105,9 +116,10 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (adhoc) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "LEAP incompatible with Ad-Hoc mode"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with Ad-Hoc mode")); + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; } @@ -116,9 +128,10 @@ verify_leap (NMSettingWirelessSecurity *s_wsec, if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, - "LEAP incompatible with 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("LEAP authentication is incompatible with 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -137,17 +150,23 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s incompatible with any WPA key management", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot use WPA key management"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } if (nm_setting_wireless_security_get_num_protos (s_wsec)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s incompatible with any 'proto' setting", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA protocols"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); return FALSE; } @@ -158,9 +177,12 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, pw = nm_setting_wireless_security_get_pairwise (s_wsec, i); if (!strcmp (pw, "tkip") || !strcmp (pw, "ccmp")) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with WPA pairwise ciphers", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA ciphers"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } } @@ -172,18 +194,24 @@ verify_no_wpa (NMSettingWirelessSecurity *s_wsec, gr = nm_setting_wireless_security_get_group (s_wsec, i); if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with WPA group ciphers", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific WPA ciphers"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); return FALSE; } } if (nm_setting_wireless_security_get_psk (s_wsec)) { g_set_error (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "%s is incompatible with a WPA Pre-Shared Key", tag); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("a connection using '%s' authentication cannot specific a WPA password"), + tag); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PSK); return FALSE; } @@ -209,18 +237,21 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (!s_8021x) { /* 802.1x key management requires an 802.1x setting */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires an 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("Dynamic WEP requires an 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* 802.1x key management must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -231,9 +262,11 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (s_8021x) { /* 802.1x setting requires 802.1x key management */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'ieee8021x' key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'ieee8021x' key management")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -242,9 +275,11 @@ verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, if (auth_alg && strcmp (auth_alg, "open")) { /* 802.1x key management must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Dynamic WEP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Dynamic WEP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -274,18 +309,21 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-psk") || !strcmp (key_mgmt, "wpa-none")) { if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-PSK incompatible with 802.1x"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("WPA-PSK authentication is incompatible with 802.1x")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* WPA must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-PSK requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-PSK requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } } @@ -293,9 +331,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-none")) { if (!adhoc) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires an Ad-Hoc mode AP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires an Ad-Hoc mode AP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_MODE); return FALSE; } @@ -304,9 +344,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_proto (s_wsec, 0) : NULL; if (n > 1 || !tmp || strcmp (tmp, "wpa")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'wpa' proto"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'wpa' protocol")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PROTO); return FALSE; } @@ -314,9 +356,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_pairwise (s_wsec, 0) : NULL; if (n > 1 || g_strcmp0 (tmp, "none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'none' pairwise cipher"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc authentication requires 'none' pairwise cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_PAIRWISE); return FALSE; } @@ -324,9 +368,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, tmp = (n > 0) ? nm_setting_wireless_security_get_group (s_wsec, 0) : NULL; if (n > 1 || !tmp || strcmp (tmp, "tkip")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA Ad-Hoc requires 'tkip' group cipher"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA Ad-Hoc requires 'tkip' group cipher")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_GROUP); return FALSE; } } @@ -336,9 +382,11 @@ verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP does not support PSK but setting requires it"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point does not support PSK but setting requires it")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -364,27 +412,31 @@ verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, if (!strcmp (key_mgmt, "wpa-eap")) { if (!s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-EAP requires an 802.1x setting"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("WPA-EAP authentication requires an 802.1x setting")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { /* WPA must use "open" authentication */ g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA-EAP requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA-EAP requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } is_wpa_eap = TRUE; } else if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Setting requires 802.1x but does not use 'wpa-eap' key management"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("802.1x setting requires 'wpa-eap' key management")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -394,9 +446,10 @@ verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP does not support 802.1x but setting requires it"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point does not support 802.1x but setting requires it")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } } @@ -421,41 +474,50 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, if (adhoc) { if (key_mgmt && strcmp (key_mgmt, "wpa-none") && strcmp (key_mgmt, "none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP mode is Ad-Hoc but setting requires Infrastructure security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point mode is Ad-Hoc but setting requires Infrastructure security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } if (s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode incompatible with 802.1x security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Ad-Hoc mode is incompatible with 802.1x security")); + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } if (leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode incompatible with LEAP security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode is incompatible with LEAP security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } if (auth_alg && strcmp (auth_alg, "open")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Ad-Hoc mode requires 'open' authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Ad-Hoc mode requires 'open' authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } } else { if (key_mgmt && !strcmp (key_mgmt, "wpa-none")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP mode is Infrastructure but setting requires Ad-Hoc security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Access point mode is Infrastructure but setting requires Ad-Hoc security")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } } @@ -465,7 +527,7 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, gboolean nm_ap_utils_complete_connection (const GByteArray *ap_ssid, - const guint8 ap_bssid[ETH_ALEN], + const char *bssid, NM80211Mode ap_mode, guint32 ap_flags, guint32 ap_wpa_flags, @@ -477,7 +539,7 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - const GByteArray *ssid; + GBytes *ssid, *ap_ssid_bytes; const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; @@ -487,26 +549,23 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, s_8021x = nm_connection_get_setting_802_1x (connection); /* Fill in missing SSID */ + ap_ssid_bytes = g_bytes_new (ap_ssid->data, ap_ssid->len); ssid = nm_setting_wireless_get_ssid (s_wifi); if (!ssid) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); - else if ( ssid->len != ap_ssid->len - || memcmp (ssid->data, ap_ssid->data, ssid->len)) { + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid_bytes, NULL); + else if (!g_bytes_equal (ssid, ap_ssid_bytes)) { g_set_error_literal (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - "Setting SSID did not match AP SSID"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); + g_bytes_unref (ap_ssid_bytes); return FALSE; } + g_bytes_unref (ap_ssid_bytes); - if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) { - GByteArray *bssid; - - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, ap_bssid, ETH_ALEN); + if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - g_byte_array_free (bssid, TRUE); - } /* And mode */ mode = nm_setting_wireless_get_mode (s_wifi); @@ -526,9 +585,10 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, if (valid == FALSE) { g_set_error (error, - NM_SETTING_WIRELESS_ERROR, - NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, - NM_SETTING_WIRELESS_MODE); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match access point")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE); return FALSE; } } else { @@ -549,9 +609,13 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, /* Make sure the connection doesn't specify security */ if (s_wsec || s_8021x) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "AP is unencrypted but setting specifies security"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("Access point is unencrypted but setting specifies security")); + if (s_wsec) + g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + else + g_prefix_error (error, "%s: ", NM_SETTING_802_1X_SETTING_NAME); return FALSE; } return TRUE; @@ -634,18 +698,20 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, /* Ensure key management is valid for WPA */ if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA incompatible with non-EAP (original) LEAP or Dynamic WEP"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with non-EAP (original) LEAP or Dynamic WEP")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); return FALSE; } /* 'shared' auth incompatible with any type of WPA */ if (auth_alg && strcmp (auth_alg, "open")) { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA incompatible with Shared Key authentication"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("WPA authentication is incompatible with Shared Key authentication")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG); return FALSE; } @@ -689,9 +755,9 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, */ } else { g_set_error_literal (error, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "Failed to determine AP security information"); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_FAILED, + _("Failed to determine AP security information")); return FALSE; } diff --git a/src/devices/wifi/nm-wifi-ap-utils.h b/src/devices/wifi/nm-wifi-ap-utils.h index 992b839d..31c12cd7 100644 --- a/src/devices/wifi/nm-wifi-ap-utils.h +++ b/src/devices/wifi/nm-wifi-ap-utils.h @@ -18,19 +18,18 @@ * (C) Copyright 2011 Red Hat, Inc. */ -#ifndef NM_WIFI_AP_UTILS_H -#define NM_WIFI_AP_UTILS_H +#ifndef __NETWORKMANAGER_WIFI_AP_UTILS_H__ +#define __NETWORKMANAGER_WIFI_AP_UTILS_H__ -#include -#include +#include #include #include #include #include gboolean nm_ap_utils_complete_connection (const GByteArray *ssid, - const guint8 bssid[ETH_ALEN], + const char *bssid, NM80211Mode mode, guint32 flags, guint32 wpa_flags, diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 363be2e3..ee07cf40 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -19,9 +19,10 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include #include -#include #include "nm-wifi-ap.h" #include "nm-wifi-ap-utils.h" @@ -45,7 +46,7 @@ typedef struct /* Scanned or cached values */ GByteArray * ssid; - struct ether_addr address; + char * address; NM80211Mode mode; gint8 strength; guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ @@ -102,6 +103,7 @@ finalize (GObject *object) g_free (priv->supplicant_path); if (priv->ssid) g_byte_array_free (priv->ssid, TRUE); + g_free (priv->address); G_OBJECT_CLASS (nm_ap_parent_class)->finalize (object); } @@ -111,6 +113,7 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMAccessPoint *ap = NM_AP (object); + GByteArray *ssid; switch (prop_id) { case PROP_FLAGS: @@ -123,7 +126,11 @@ set_property (GObject *object, guint prop_id, nm_ap_set_rsn_flags (ap, g_value_get_uint (value)); break; case PROP_SSID: - nm_ap_set_ssid (ap, (GByteArray *) g_value_get_boxed (value)); + ssid = g_value_get_boxed (value); + if (ssid) + nm_ap_set_ssid (ap, ssid->data, ssid->len); + else + nm_ap_set_ssid (ap, NULL, 0); break; case PROP_FREQUENCY: nm_ap_set_freq (ap, g_value_get_uint (value)); @@ -176,7 +183,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->freq); break; case PROP_HW_ADDRESS: - g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->address, ARPHRD_ETHER)); + g_value_set_string (value, priv->address); break; case PROP_MODE: g_value_set_uint (value, priv->mode); @@ -219,81 +226,72 @@ nm_ap_class_init (NMAccessPointClass *ap_class) /* properties */ g_object_class_install_property (object_class, PROP_FLAGS, - g_param_spec_uint (NM_AP_FLAGS, - "Flags", - "Flags", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_FLAGS_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + 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_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WPA_FLAGS, - g_param_spec_uint (NM_AP_WPA_FLAGS, - "WPA Flags", - "WPA Flags", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + 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_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSN_FLAGS, - g_param_spec_uint (NM_AP_RSN_FLAGS, - "RSN Flags", - "RSN Flags", - NM_802_11_AP_SEC_NONE, - all_sec_flags, - NM_802_11_AP_SEC_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + 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_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SSID, - g_param_spec_boxed (NM_AP_SSID, - "SSID", - "SSID", + g_param_spec_boxed (NM_AP_SSID, "", "", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_FREQUENCY, - g_param_spec_uint (NM_AP_FREQUENCY, - "Frequency", - "Frequency", - 0, 10000, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_FREQUENCY, "", "", + 0, 10000, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HW_ADDRESS, - g_param_spec_string (NM_AP_HW_ADDRESS, - "MAC Address", - "Hardware MAC address", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_string (NM_AP_HW_ADDRESS, "", "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MODE, - g_param_spec_uint (NM_AP_MODE, - "Mode", - "Mode", - NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_MODE, "", "", + NM_802_11_MODE_ADHOC, NM_802_11_MODE_INFRA, NM_802_11_MODE_INFRA, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_MAX_BITRATE, - g_param_spec_uint (NM_AP_MAX_BITRATE, - "Max Bitrate", - "Max Bitrate", - 0, G_MAXUINT16, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_AP_MAX_BITRATE, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STRENGTH, - g_param_spec_char (NM_AP_STRENGTH, - "Strength", - "Strength", - G_MININT8, G_MAXINT8, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_char (NM_AP_STRENGTH, "", "", + G_MININT8, G_MAXINT8, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (ap_class), @@ -402,7 +400,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (!strcmp (key, "SSID")) { guint32 len = MIN (32, array->len); - GByteArray *ssid; /* Stupid ieee80211 layer uses */ if (((len == 8) || (len == 9)) @@ -412,18 +409,15 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len)) return; - ssid = g_byte_array_sized_new (len); - g_byte_array_append (ssid, (const guint8 *) array->data, len); - nm_ap_set_ssid (ap, ssid); - g_byte_array_free (ssid, TRUE); + nm_ap_set_ssid (ap, (const guint8 *) array->data, len); } else if (!strcmp (key, "BSSID")) { - struct ether_addr addr; + char *addr; if (array->len != ETH_ALEN) return; - memset (&addr, 0, sizeof (struct ether_addr)); - memcpy (&addr, array->data, ETH_ALEN); - nm_ap_set_address (ap, &addr); + addr = nm_utils_hwaddr_ntoa (array->data, array->len); + nm_ap_set_address (ap, addr); + g_free (addr); } else if (!strcmp (key, "Rates")) { guint32 maxrate = 0; int i; @@ -483,7 +477,7 @@ NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties) { NMAccessPoint *ap; - const struct ether_addr * addr; + const char *addr; const char bad_bssid1[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const char bad_bssid2[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -498,8 +492,8 @@ nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties) /* ignore APs with invalid BSSIDs */ addr = nm_ap_get_address (ap); - if ( !(memcmp (addr->ether_addr_octet, bad_bssid1, ETH_ALEN)) - || !(memcmp (addr->ether_addr_octet, bad_bssid2, ETH_ALEN))) { + if ( nm_utils_hwaddr_matches (addr, -1, bad_bssid1, ETH_ALEN) + || nm_utils_hwaddr_matches (addr, -1, bad_bssid2, ETH_ALEN)) { g_object_unref (ap); return NULL; } @@ -597,7 +591,7 @@ nm_ap_new_fake_from_connection (NMConnection *connection) NMAccessPoint *ap; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; - const GByteArray *ssid; + GBytes *ssid; const char *mode, *band, *key_mgmt; guint32 channel; NM80211ApSecurityFlags flags; @@ -610,11 +604,11 @@ nm_ap_new_fake_from_connection (NMConnection *connection) ssid = nm_setting_wireless_get_ssid (s_wireless); g_return_val_if_fail (ssid != NULL, NULL); - g_return_val_if_fail (ssid->len > 0, NULL); + g_return_val_if_fail (g_bytes_get_size (ssid) > 0, NULL); ap = nm_ap_new (); nm_ap_set_fake (ap, TRUE); - nm_ap_set_ssid (ap, ssid); + nm_ap_set_ssid (ap, g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); // FIXME: bssid too? @@ -720,10 +714,6 @@ error: return NULL; } - -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] - void nm_ap_dump (NMAccessPoint *ap, const char *prefix) { @@ -737,7 +727,7 @@ nm_ap_dump (NMAccessPoint *ap, const char *prefix) prefix, priv->ssid ? nm_utils_escape_ssid (priv->ssid->data, priv->ssid->len) : "(none)", ap); - nm_log_dbg (LOGD_WIFI_SCAN, " BSSID " MAC_FMT, MAC_ARG (priv->address.ether_addr_octet)); + nm_log_dbg (LOGD_WIFI_SCAN, " BSSID %s", str_if_set (priv->address, "(none)")); nm_log_dbg (LOGD_WIFI_SCAN, " mode %d", priv->mode); nm_log_dbg (LOGD_WIFI_SCAN, " flags 0x%X", priv->flags); nm_log_dbg (LOGD_WIFI_SCAN, " wpa flags 0x%X", priv->wpa_flags); @@ -786,20 +776,18 @@ const GByteArray * nm_ap_get_ssid (const NMAccessPoint *ap) } void -nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) +nm_ap_set_ssid (NMAccessPoint *ap, const guint8 *ssid, gsize len) { NMAccessPointPrivate *priv; g_return_if_fail (NM_IS_AP (ap)); + g_return_if_fail (ssid == NULL || len > 0); priv = NM_AP_GET_PRIVATE (ap); - if (ssid == priv->ssid) - return; - /* same SSID */ - if ((ssid && priv->ssid) && (ssid->len == priv->ssid->len)) { - if (!memcmp (ssid->data, priv->ssid->data, ssid->len)) + if ((ssid && priv->ssid) && (len == priv->ssid->len)) { + if (!memcmp (ssid, priv->ssid->data, len)) return; } @@ -809,14 +797,8 @@ nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) } if (ssid) { - /* Should never get zero-length SSIDs */ - g_warn_if_fail (ssid->len > 0); - - if (ssid->len) { - priv->ssid = g_byte_array_sized_new (ssid->len); - priv->ssid->len = ssid->len; - memcpy (priv->ssid->data, ssid->data, ssid->len); - } + priv->ssid = g_byte_array_new (); + g_byte_array_append (priv->ssid, ssid, len); } g_object_notify (G_OBJECT (ap), NM_AP_SSID); @@ -897,24 +879,28 @@ nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags) * Get/set functions for address * */ -const struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap) +const char * +nm_ap_get_address (const NMAccessPoint *ap) { g_return_val_if_fail (NM_IS_AP (ap), NULL); - return &NM_AP_GET_PRIVATE (ap)->address; + return NM_AP_GET_PRIVATE (ap)->address; } -void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr) +void +nm_ap_set_address (NMAccessPoint *ap, const char *addr) { NMAccessPointPrivate *priv; g_return_if_fail (NM_IS_AP (ap)); g_return_if_fail (addr != NULL); + g_return_if_fail (nm_utils_hwaddr_valid (addr, ETH_ALEN)); priv = NM_AP_GET_PRIVATE (ap); - if (memcmp (addr, &priv->address, sizeof (priv->address))) { - memcpy (&NM_AP_GET_PRIVATE (ap)->address, addr, sizeof (struct ether_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); } } @@ -1118,9 +1104,10 @@ nm_ap_check_compatible (NMAccessPoint *self, NMAccessPointPrivate *priv; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; + GBytes *ssid; const char *mode; const char *band; - const GByteArray *bssid; + const char *bssid; guint32 channel; g_return_val_if_fail (NM_IS_AP (self), FALSE); @@ -1132,11 +1119,19 @@ nm_ap_check_compatible (NMAccessPoint *self, if (s_wireless == NULL) return FALSE; - if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), priv->ssid, TRUE)) + ssid = nm_setting_wireless_get_ssid (s_wireless); + if ( (ssid && !priv->ssid) + || (priv->ssid && !ssid)) + return FALSE; + + if ( ssid && priv->ssid && + !nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + priv->ssid->data, priv->ssid->len, + TRUE)) return FALSE; bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid && memcmp (bssid->data, &priv->address, ETH_ALEN)) + if (bssid && (!priv->address || !nm_utils_hwaddr_matches (bssid, -1, priv->address, -1))) return FALSE; mode = nm_setting_wireless_get_mode (s_wireless); @@ -1190,7 +1185,7 @@ nm_ap_complete_connection (NMAccessPoint *self, g_return_val_if_fail (connection != NULL, FALSE); return nm_ap_utils_complete_connection (priv->ssid, - priv->address.ether_addr_octet, + priv->address, priv->mode, priv->flags, priv->wpa_flags, @@ -1233,27 +1228,29 @@ nm_ap_match_in_list (NMAccessPoint *find_ap, for (iter = ap_list; iter; iter = g_slist_next (iter)) { NMAccessPoint * list_ap = NM_AP (iter->data); const GByteArray * list_ssid = nm_ap_get_ssid (list_ap); - const struct ether_addr * list_addr = nm_ap_get_address (list_ap); + const char * list_addr = nm_ap_get_address (list_ap); const GByteArray * find_ssid = nm_ap_get_ssid (find_ap); - const struct ether_addr * find_addr = nm_ap_get_address (find_ap); + const char * find_addr = nm_ap_get_address (find_ap); /* SSID match; if both APs are hiding their SSIDs, * let matching continue on BSSID and other properties */ if ( (!list_ssid && find_ssid) - || (list_ssid && !find_ssid) - || !nm_utils_same_ssid (list_ssid, find_ssid, TRUE)) + || (list_ssid && !find_ssid)) + continue; + if ( list_ssid + && find_ssid + && !nm_utils_same_ssid (list_ssid->data, list_ssid->len, + find_ssid->data, find_ssid->len, + TRUE)) continue; /* BSSID match */ - if ( (strict_match || nm_ethernet_address_is_valid (find_addr)) - && nm_ethernet_address_is_valid (list_addr) - && memcmp (list_addr->ether_addr_octet, - find_addr->ether_addr_octet, - ETH_ALEN) != 0) { + if ( (strict_match || nm_ethernet_address_is_valid (find_addr, -1)) + && nm_ethernet_address_is_valid (list_addr, -1) + && !nm_utils_hwaddr_matches (list_addr, -1, find_addr, -1)) continue; - } /* mode match */ if (nm_ap_get_mode (list_ap) != nm_ap_get_mode (find_ap)) diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index f51fa078..0abb28fc 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -19,12 +19,12 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_ACCESS_POINT_H -#define NM_ACCESS_POINT_H +#ifndef __NETWORKMANAGER_ACCESS_POINT_H__ +#define __NETWORKMANAGER_ACCESS_POINT_H__ #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-connection.h" #define NM_TYPE_AP (nm_ap_get_type ()) @@ -60,62 +60,62 @@ NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path, NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection); void nm_ap_export_to_dbus (NMAccessPoint *ap); -const char * nm_ap_get_dbus_path (NMAccessPoint *ap); +const char *nm_ap_get_dbus_path (NMAccessPoint *ap); -const char * nm_ap_get_supplicant_path (NMAccessPoint *ap); -void nm_ap_set_supplicant_path (NMAccessPoint *ap, - const char *path); +const char *nm_ap_get_supplicant_path (NMAccessPoint *ap); +void nm_ap_set_supplicant_path (NMAccessPoint *ap, + const char *path); -const GByteArray * nm_ap_get_ssid (const NMAccessPoint * ap); -void nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid); +const GByteArray *nm_ap_get_ssid (const NMAccessPoint * ap); +void nm_ap_set_ssid (NMAccessPoint * ap, const guint8 * ssid, gsize len); -NM80211ApFlags nm_ap_get_flags (NMAccessPoint *ap); -void nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags); +NM80211ApFlags nm_ap_get_flags (NMAccessPoint *ap); +void nm_ap_set_flags (NMAccessPoint *ap, NM80211ApFlags flags); NM80211ApSecurityFlags nm_ap_get_wpa_flags (NMAccessPoint *ap); void nm_ap_set_wpa_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); -NM80211ApSecurityFlags nm_ap_get_rsn_flags (NMAccessPoint *ap); -void nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); +NM80211ApSecurityFlags nm_ap_get_rsn_flags (NMAccessPoint *ap); +void nm_ap_set_rsn_flags (NMAccessPoint *ap, NM80211ApSecurityFlags flags); -const struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap); -void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr *addr); +const char *nm_ap_get_address (const NMAccessPoint *ap); +void nm_ap_set_address (NMAccessPoint *ap, const char *addr); -NM80211Mode nm_ap_get_mode (NMAccessPoint *ap); -void nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode); +NM80211Mode nm_ap_get_mode (NMAccessPoint *ap); +void nm_ap_set_mode (NMAccessPoint *ap, const NM80211Mode mode); -gboolean nm_ap_is_hotspot (NMAccessPoint *ap); +gboolean nm_ap_is_hotspot (NMAccessPoint *ap); -gint8 nm_ap_get_strength (NMAccessPoint *ap); -void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength); +gint8 nm_ap_get_strength (NMAccessPoint *ap); +void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength); -guint32 nm_ap_get_freq (NMAccessPoint *ap); -void nm_ap_set_freq (NMAccessPoint *ap, guint32 freq); +guint32 nm_ap_get_freq (NMAccessPoint *ap); +void nm_ap_set_freq (NMAccessPoint *ap, guint32 freq); -guint32 nm_ap_get_max_bitrate (NMAccessPoint *ap); -void nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate); +guint32 nm_ap_get_max_bitrate (NMAccessPoint *ap); +void nm_ap_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate); -gboolean nm_ap_get_fake (const NMAccessPoint *ap); -void nm_ap_set_fake (NMAccessPoint *ap, gboolean fake); +gboolean nm_ap_get_fake (const NMAccessPoint *ap); +void nm_ap_set_fake (NMAccessPoint *ap, gboolean fake); -gboolean nm_ap_get_broadcast (NMAccessPoint *ap); -void nm_ap_set_broadcast (NMAccessPoint *ap, gboolean broadcast); +gboolean nm_ap_get_broadcast (NMAccessPoint *ap); +void nm_ap_set_broadcast (NMAccessPoint *ap, gboolean broadcast); -gint32 nm_ap_get_last_seen (const NMAccessPoint *ap); -void nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen); +gint32 nm_ap_get_last_seen (const NMAccessPoint *ap); +void nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen); -gboolean nm_ap_check_compatible (NMAccessPoint *self, - NMConnection *connection); +gboolean nm_ap_check_compatible (NMAccessPoint *self, + NMConnection *connection); -gboolean nm_ap_complete_connection (NMAccessPoint *self, - NMConnection *connection, - gboolean lock_bssid, - GError **error); +gboolean nm_ap_complete_connection (NMAccessPoint *self, + NMConnection *connection, + gboolean lock_bssid, + GError **error); NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap, GSList *ap_list, gboolean strict_match); -void nm_ap_dump (NMAccessPoint *ap, const char *prefix); +void nm_ap_dump (NMAccessPoint *ap, const char *prefix); -#endif /* NM_ACCESS_POINT_H */ +#endif /* __NETWORKMANAGER_ACCESS_POINT_H__ */ diff --git a/src/devices/wifi/nm-wifi-enum-types.c b/src/devices/wifi/nm-wifi-enum-types.c index e914cfd6..7cce51cd 100644 --- a/src/devices/wifi/nm-wifi-enum-types.c +++ b/src/devices/wifi/nm-wifi-enum-types.c @@ -9,50 +9,6 @@ #include "nm-wifi-ap.h" #include "nm-device-olpc-mesh.h" -GType -nm_wifi_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS, "NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS", "ConnectionNotWireless" }, - { NM_WIFI_ERROR_CONNECTION_INVALID, "NM_WIFI_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND", "AccessPointNotFound" }, - { NM_WIFI_ERROR_SCAN_NOT_ALLOWED, "NM_WIFI_ERROR_SCAN_NOT_ALLOWED", "ScanNotAllowed" }, - { NM_WIFI_ERROR_AP_MODE_UNSUPPORTED, "NM_WIFI_ERROR_AP_MODE_UNSUPPORTED", "ApModeUnsupported" }, - { NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED, "NM_WIFI_ERROR_ADHOC_MODE_UNSUPPORTED", "AdhocModeUnsupported" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMWifiError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_olpc_mesh_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH, "NM_OLPC_MESH_ERROR_CONNECTION_NOT_MESH", "ConnectionNotMesh" }, - { NM_OLPC_MESH_ERROR_CONNECTION_INVALID, "NM_OLPC_MESH_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE, "NM_OLPC_MESH_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMOlpcMeshError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} diff --git a/src/devices/wifi/nm-wifi-enum-types.h b/src/devices/wifi/nm-wifi-enum-types.h index d4dca5bf..7fc64cd1 100644 --- a/src/devices/wifi/nm-wifi-enum-types.h +++ b/src/devices/wifi/nm-wifi-enum-types.h @@ -9,10 +9,6 @@ #include G_BEGIN_DECLS -GType nm_wifi_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) -GType nm_olpc_mesh_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_OLPC_MESH_ERROR (nm_olpc_mesh_error_get_type ()) G_END_DECLS #endif /* __NM_WIFI_ENUM_TYPES_H__ */ diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 02ad93f4..4093c612 100644 --- a/src/devices/wifi/nm-wifi-factory.c +++ b/src/devices/wifi/nm-wifi-factory.c @@ -18,12 +18,15 @@ * Copyright (C) 2011 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include "nm-device-factory.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" #include "nm-settings-connection.h" +#include "nm-platform.h" #define NM_TYPE_WIFI_FACTORY (nm_wifi_factory_get_type ()) #define NM_WIFI_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_FACTORY, NMWifiFactory)) @@ -45,20 +48,12 @@ G_DEFINE_TYPE_EXTENDED (NMWifiFactory, nm_wifi_factory, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_WIFI - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WIFI_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /**************************************************************************/ static NMDevice * @@ -71,10 +66,17 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) return NULL; } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_WIFI; +} + static void device_factory_interface_init (NMDeviceFactory *factory_iface) { factory_iface->new_link = new_link; + factory_iface->get_device_type = get_device_type; } static void diff --git a/src/devices/wifi/tests/Makefile.am b/src/devices/wifi/tests/Makefile.am index 2667c5f1..09c6401f 100644 --- a/src/devices/wifi/tests/Makefile.am +++ b/src/devices/wifi/tests/Makefile.am @@ -1,14 +1,13 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/platform \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I${top_srcdir}/src/platform \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/devices/wifi \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/devices/wifi/tests/Makefile.in b/src/devices/wifi/tests/Makefile.in index c0e75eed..a8ae2e9d 100644 --- a/src/devices/wifi/tests/Makefile.in +++ b/src/devices/wifi/tests/Makefile.in @@ -205,6 +205,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -328,6 +330,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -347,6 +350,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -373,7 +377,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -454,15 +458,14 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/platform \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I${top_srcdir}/src/platform \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/devices/wifi \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager-wifi"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/devices/wifi/tests/test-wifi-ap-utils.c b/src/devices/wifi/tests/test-wifi-ap-utils.c index 36d58f2a..fb335b89 100644 --- a/src/devices/wifi/tests/test-wifi-ap-utils.c +++ b/src/devices/wifi/tests/test-wifi-ap-utils.c @@ -18,16 +18,15 @@ * */ +#include "config.h" + #include #include #include "nm-wifi-ap-utils.h" #include "nm-dbus-glib-types.h" -#include "nm-setting-connection.h" -#include "nm-setting-wireless.h" -#include "nm-setting-wireless-security.h" -#include "nm-setting-8021x.h" +#include "nm-core-internal.h" #define DEBUG 1 @@ -66,7 +65,7 @@ static gboolean complete_connection (const char *ssid, - const guint8 bssid[ETH_ALEN], + const char *bssid, NM80211Mode mode, guint32 flags, guint32 wpa_flags, @@ -113,7 +112,7 @@ set_items (NMSetting *setting, const KeyData *items) { const KeyData *item; GParamSpec *pspec; - GByteArray *tmp; + GBytes *tmp; for (item = items; item && item->key; item++) { g_assert (item->key); @@ -137,12 +136,11 @@ set_items (NMSetting *setting, const KeyData *items) g_assert (item->str == NULL); g_object_set (G_OBJECT (setting), item->key, foo, NULL); - } else if (pspec->value_type == DBUS_TYPE_G_UCHAR_ARRAY) { + } else if (pspec->value_type == G_TYPE_BYTES) { g_assert (item->str); - tmp = g_byte_array_sized_new (strlen (item->str)); - g_byte_array_append (tmp, (const guint8 *) item->str, strlen (item->str)); + tmp = g_bytes_new (item->str, strlen (item->str)); g_object_set (G_OBJECT (setting), item->key, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_bytes_unref (tmp); } else { /* Special types, check based on property name */ if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) @@ -217,31 +215,26 @@ fill_8021x (NMConnection *connection, const KeyData items[]) static NMConnection * create_basic (const char *ssid, - const guint8 *bssid, + const char *bssid, NM80211Mode mode) { NMConnection *connection; NMSettingWireless *s_wifi = NULL; - GByteArray *tmp; + GBytes *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); /* SSID */ - tmp = g_byte_array_sized_new (strlen (ssid)); - g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid)); + tmp = g_bytes_new (ssid, strlen (ssid)); g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL); - g_byte_array_free (tmp, TRUE); + g_bytes_unref (tmp); /* BSSID */ - if (bssid) { - tmp = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (tmp, bssid, ETH_ALEN); - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, tmp, NULL); - g_byte_array_free (tmp, TRUE); - } + if (bssid) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); if (mode == NM_802_11_MODE_INFRA) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); @@ -259,12 +252,12 @@ static void test_lock_bssid (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -283,7 +276,7 @@ static void test_open_ap_empty_connection (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; gboolean success; GError *error = NULL; @@ -292,7 +285,7 @@ test_open_ap_empty_connection (void) * SSID and Infra modes of the given AP details. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -311,7 +304,7 @@ static void test_open_ap_leap_connection_1 (gconstpointer add_wifi) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0 }, { NULL } }; gboolean success; GError *error = NULL; @@ -321,7 +314,7 @@ test_open_ap_leap_connection_1 (gconstpointer add_wifi) * the AP to have the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -332,7 +325,7 @@ test_open_ap_leap_connection_1 (gconstpointer add_wifi) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -343,7 +336,7 @@ static void test_open_ap_leap_connection_2 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; gboolean success; GError *error = NULL; @@ -352,7 +345,7 @@ test_open_ap_leap_connection_2 (void) * WEP or LEAP) is rejected when completion is attempted with an open AP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -362,7 +355,7 @@ test_open_ap_leap_connection_2 (void) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -373,7 +366,7 @@ static void test_open_ap_wep_connection (gconstpointer add_wifi) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0 }, { NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0 }, @@ -386,7 +379,7 @@ test_open_ap_wep_connection (gconstpointer add_wifi) * attempted with an open AP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -396,7 +389,7 @@ test_open_ap_wep_connection (gconstpointer add_wifi) FALSE, src, &error); /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING); g_object_unref (src); } @@ -410,11 +403,12 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, guint32 wpa_flags, guint32 rsn_flags, gboolean add_wifi, + guint error_code, NMConnection *expected) { NMConnection *src; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData exp_wifi[] = { { NM_SETTING_WIRELESS_SSID, ssid, 0 }, { NM_SETTING_WIRELESS_MODE, "infrastructure", 0 }, @@ -427,7 +421,7 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, both_wsec); @@ -438,7 +432,7 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, fill_wifi (expected, exp_wifi); fill_wsec (expected, both_wsec); } - COMPARE (src, expected, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, expected, success, error, NM_CONNECTION_ERROR, error_code); g_object_unref (src); } @@ -454,7 +448,9 @@ test_open_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -468,7 +464,9 @@ test_open_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE, NULL); + TRUE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -481,7 +479,9 @@ test_open_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -495,7 +495,9 @@ test_open_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } static void @@ -508,7 +510,9 @@ test_open_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_SETTING, + NULL); } /*******************************************/ @@ -520,11 +524,10 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, guint32 wpa_flags, guint32 rsn_flags, gboolean add_wifi, - guint error_domain, guint error_code) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_empty[] = { { NULL } }; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, @@ -533,7 +536,7 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, gboolean success; GError *error = NULL; - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -542,7 +545,7 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, flags, wpa_flags, rsn_flags, FALSE, src, &error); /* Failure expected */ - COMPARE (src, NULL, success, error, error_domain, error_code); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, error_code); g_object_unref (src); } @@ -618,38 +621,23 @@ rsn_flags_for_idx (guint32 idx) g_assert_not_reached (); } -static guint32 -error_domain_for_idx (guint32 idx, guint num) -{ - if (idx == IDX_OPEN) - return NM_SETTING_WIRELESS_SECURITY_ERROR; - else if (idx == IDX_PRIV) { - if (num <= 3) - return NM_SETTING_802_1X_ERROR; - else - return NM_SETTING_WIRELESS_SECURITY_ERROR; - } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP - || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) - return NM_SETTING_WIRELESS_SECURITY_ERROR; - else - g_assert_not_reached (); -} - static guint32 error_code_for_idx (guint32 idx, guint num) { if (idx == IDX_OPEN) - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + return NM_CONNECTION_ERROR_INVALID_SETTING; else if (idx == IDX_PRIV) { if (num <= 3) - return NM_SETTING_802_1X_ERROR_MISSING_PROPERTY; + return NM_CONNECTION_ERROR_MISSING_PROPERTY; else - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; - } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + } else if ( idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP) - return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + if (num == 4) + return NM_CONNECTION_ERROR_INVALID_PROPERTY; + else + return NM_CONNECTION_ERROR_INVALID_SETTING; else g_assert_not_reached (); } @@ -664,7 +652,6 @@ test_ap_wpa_eap_connection_1 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 1), error_code_for_idx (idx, 1)); } @@ -678,7 +665,6 @@ test_ap_wpa_eap_connection_2 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), TRUE, - error_domain_for_idx (idx, 2), error_code_for_idx (idx, 2)); } @@ -692,7 +678,6 @@ test_ap_wpa_eap_connection_3 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 3), error_code_for_idx (idx, 3)); } @@ -706,7 +691,6 @@ test_ap_wpa_eap_connection_4 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 4), error_code_for_idx (idx, 4)); } @@ -720,7 +704,6 @@ test_ap_wpa_eap_connection_5 (gconstpointer data) wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), FALSE, - error_domain_for_idx (idx, 5), error_code_for_idx (idx, 5)); } @@ -730,7 +713,7 @@ static void test_priv_ap_empty_connection (void) { NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; const KeyData exp_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0 }, @@ -742,7 +725,7 @@ test_priv_ap_empty_connection (void) * connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -765,7 +748,7 @@ test_priv_ap_leap_connection_1 (gconstpointer add_wifi) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *leap_username = "Bill Smith"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, @@ -784,7 +767,7 @@ test_priv_ap_leap_connection_1 (gconstpointer add_wifi) * with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); if (add_wifi) fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -810,7 +793,7 @@ static void test_priv_ap_leap_connection_2 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, @@ -823,7 +806,7 @@ test_priv_ap_leap_connection_2 (void) * with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -832,7 +815,7 @@ test_priv_ap_leap_connection_2 (void) FALSE, src, &error); /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); g_object_unref (src); } @@ -844,7 +827,7 @@ test_priv_ap_dynamic_wep_1 (void) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, @@ -866,7 +849,7 @@ test_priv_ap_dynamic_wep_1 (void) * Dynamic WEP connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, both_8021x); @@ -892,7 +875,7 @@ test_priv_ap_dynamic_wep_2 (void) { NMConnection *src, *expected; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; @@ -913,7 +896,7 @@ test_priv_ap_dynamic_wep_2 (void) * WEP connection when completed with an AP with the Privacy bit set. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, both_8021x); @@ -938,7 +921,7 @@ static void test_priv_ap_dynamic_wep_3 (void) { NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0 }, { NULL } }; @@ -954,7 +937,7 @@ test_priv_ap_dynamic_wep_3 (void) * setting is rejected, as 802.1x is incompatible with 'shared' auth. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); fill_8021x (src, src_8021x); @@ -964,7 +947,7 @@ test_priv_ap_dynamic_wep_3 (void) FALSE, src, &error); /* Expect failure; shared is not compatible with dynamic WEP */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -982,7 +965,9 @@ test_priv_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -996,7 +981,9 @@ test_priv_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE, NULL); + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1011,7 +998,9 @@ test_priv_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1026,7 +1015,9 @@ test_priv_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1041,7 +1032,9 @@ test_priv_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } /*******************************************/ @@ -1051,7 +1044,7 @@ test_wpa_ap_empty_connection (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src, *expected; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *ssid = "blahblah"; const KeyData exp_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, @@ -1065,7 +1058,7 @@ test_wpa_ap_empty_connection (gconstpointer data) * or RSN flags. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), @@ -1089,7 +1082,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) guint idx = GPOINTER_TO_UINT (data); NMConnection *src; const char *ssid = "blahblah"; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const char *leap_username = "Bill Smith"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, @@ -1102,7 +1095,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) * rejected since WPA APs (usually) do not support LEAP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection (ssid, bssid, @@ -1112,7 +1105,7 @@ test_wpa_ap_leap_connection_1 (gconstpointer data) FALSE, src, &error); /* Expect failure here; WPA APs don't support old-school LEAP */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1124,7 +1117,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, @@ -1136,7 +1129,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) * rejected since WPA APs (usually) do not support LEAP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -1146,7 +1139,7 @@ test_wpa_ap_leap_connection_2 (gconstpointer data) FALSE, src, &error); /* We expect failure here, we need a LEAP username */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1158,7 +1151,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) { guint idx = GPOINTER_TO_UINT (data); NMConnection *src; - const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *bssid = "01:02:03:04:05:06"; const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; @@ -1169,7 +1162,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) * rejected since WPA APs (usually) do not support Dynamic WEP. */ - src = nm_connection_new (); + src = nm_simple_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, @@ -1179,7 +1172,7 @@ test_wpa_ap_dynamic_wep_connection (gconstpointer data) FALSE, src, &error); /* We expect failure here since Dynamic WEP is incompatible with WPA */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + COMPARE (src, NULL, success, error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -1196,13 +1189,15 @@ test_wpa_ap_wpa_psk_connection_1 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1216,13 +1211,15 @@ test_wpa_ap_wpa_psk_connection_2 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - TRUE, expected); + TRUE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1236,13 +1233,15 @@ test_wpa_ap_wpa_psk_connection_3 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, "open", NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } @@ -1254,7 +1253,9 @@ test_wpa_ap_wpa_psk_connection_4 (gconstpointer data) NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, NULL); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + NULL); } static void @@ -1267,13 +1268,15 @@ test_wpa_ap_wpa_psk_connection_5 (gconstpointer data) { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, { NULL } }; - expected = nm_connection_new (); + expected = nm_simple_connection_new (); fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base ("wpa-psk", "open", NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx (idx), rsn_flags_for_idx (idx), - FALSE, expected); + FALSE, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + expected); g_object_unref (expected); } diff --git a/src/devices/wimax/Makefile.am b/src/devices/wimax/Makefile.am index def8bf62..555b5ff2 100644 --- a/src/devices/wimax/Makefile.am +++ b/src/devices/wimax/Makefile.am @@ -1,20 +1,16 @@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(IWMX_SDK_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(IWMX_SDK_CFLAGS) pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la diff --git a/src/devices/wimax/Makefile.in b/src/devices/wimax/Makefile.in index ba16d277..f1ffb09c 100644 --- a/src/devices/wimax/Makefile.in +++ b/src/devices/wimax/Makefile.in @@ -215,6 +215,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -338,6 +340,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -357,6 +360,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -383,7 +387,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -465,20 +469,16 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wimax"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(IWMX_SDK_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(GUDEV_CFLAGS) + $(IWMX_SDK_CFLAGS) pkglib_LTLIBRARIES = libnm-device-plugin-wimax.la SYMBOL_VIS_FILE = $(srcdir)/exports.ver diff --git a/src/devices/wimax/exports.ver b/src/devices/wimax/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wimax/exports.ver +++ b/src/devices/wimax/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wimax/iwmxsdk.c b/src/devices/wimax/iwmxsdk.c index d1ef7b68..1c2c6821 100644 --- a/src/devices/wimax/iwmxsdk.c +++ b/src/devices/wimax/iwmxsdk.c @@ -19,24 +19,22 @@ * */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" #include #include #include #include #include -#include #include -#include +#include "nm-wimax-util.h" + #include #include -#include "logging/nm-logging.h" +#include "nm-logging.h" #include "iwmxsdk.h" static WIMAX_API_DEVICE_ID g_api; diff --git a/src/devices/wimax/iwmxsdk.h b/src/devices/wimax/iwmxsdk.h index 785ca8c2..c8e76696 100644 --- a/src/devices/wimax/iwmxsdk.h +++ b/src/devices/wimax/iwmxsdk.h @@ -19,10 +19,11 @@ * */ -#ifndef IWMXSDK_H -#define IWMXSDK_H +#ifndef __IWMXSDK_H__ +#define __IWMXSDK_H__ + +#include "nm-wimax-util.h" -#include #include #include @@ -108,4 +109,4 @@ int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk); int iwmx_sdk_api_init(void); void iwmx_sdk_api_exit(void); -#endif /* IWMXSDK_H */ +#endif /* __IWMXSDK_H__ */ diff --git a/src/devices/wimax/nm-device-wimax.c b/src/devices/wimax/nm-device-wimax.c index 1bdda489..466cd979 100644 --- a/src/devices/wimax/nm-device-wimax.c +++ b/src/devices/wimax/nm-device-wimax.c @@ -19,14 +19,17 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include #include #include #include -#include #include -#include -#include + +#include + +#include "nm-wimax-util.h" #include #include @@ -36,8 +39,10 @@ #include "nm-logging.h" #include "nm-device-private.h" #include "NetworkManagerUtils.h" +#include "nm-active-connection.h" #include "nm-dbus-manager.h" #include "nm-connection.h" +#include "nm-platform.h" #include "nm-setting-connection.h" #include "nm-setting-wimax.h" #include "nm-utils.h" @@ -110,19 +115,6 @@ typedef struct { /***********************************************************/ -#define NM_WIMAX_ERROR (nm_wimax_error_quark ()) - -static GQuark -nm_wimax_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-wimax-error"); - return quark; -} - -/***********************************************************/ - static gboolean impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error) { @@ -316,7 +308,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) NMSettingConnection *s_con; NMSettingWimax *s_wimax; const char *connection_type; - const GByteArray *mac; + const char *mac; if (!NM_DEVICE_CLASS (nm_device_wimax_parent_class)->check_connection_compatible (device, connection)) return FALSE; @@ -333,7 +325,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return FALSE; mac = nm_setting_wimax_get_mac_address (s_wimax); - if (mac && memcmp (mac->data, nm_device_get_hw_address (device, NULL), ETH_ALEN)) + if (mac && !nm_utils_hwaddr_matches (mac, -1, nm_device_get_hw_address (device), -1)) return FALSE; return TRUE; @@ -372,9 +364,8 @@ complete_connection (NMDevice *device, NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMSettingWimax *s_wimax; - const GByteArray *setting_mac; - const guint8 *hw_address; - char *format; + const char *setting_mac; + const char *hw_address; const char *nsp_name = NULL; NMWimaxNsp *nsp = NULL; GSList *iter; @@ -385,8 +376,8 @@ complete_connection (NMDevice *device, /* If not given a specific object, we need at minimum an NSP name */ if (!s_wimax) { g_set_error_literal (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting is required if no NSP path was given."); return FALSE; } @@ -394,8 +385,8 @@ complete_connection (NMDevice *device, nsp_name = nm_setting_wimax_get_network_name (s_wimax); if (!nsp_name || !strlen (nsp_name)) { g_set_error_literal (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_CONNECTION_INVALID, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting with a valid network name is required if no NSP path was given."); return FALSE; } @@ -422,8 +413,8 @@ complete_connection (NMDevice *device, if (!nsp) { g_set_error (error, - NM_WIMAX_ERROR, - NM_WIMAX_ERROR_NSP_NOT_FOUND, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "The NSP %s was not in the scan list.", specific_object); return FALSE; @@ -439,38 +430,31 @@ complete_connection (NMDevice *device, } g_assert (nsp_name); - format = g_strdup_printf ("%s %%d", nsp_name); nm_utils_complete_generic (connection, NM_SETTING_WIMAX_SETTING_NAME, existing_connections, - format, nsp_name, + nsp_name, + NULL, TRUE); - g_free (format); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); setting_mac = nm_setting_wimax_get_mac_address (s_wimax); - hw_address = nm_device_get_hw_address (device, NULL); + hw_address = nm_device_get_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ - if (memcmp (setting_mac->data, hw_address, ETH_ALEN)) { - g_set_error (error, - NM_SETTING_WIMAX_ERROR, - NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, - NM_SETTING_WIMAX_MAC_ADDRESS); + if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("connection does not match device")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS); return FALSE; } } else { - GByteArray *mac; - const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - /* Lock the connection to this device by default */ - if (memcmp (hw_address, null_mac, ETH_ALEN)) { - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, hw_address, ETH_ALEN); - g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } + if (!nm_utils_hwaddr_matches (hw_address, -1, NULL, ETH_ALEN)) + g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, hw_address, NULL); } return TRUE; @@ -1047,7 +1031,7 @@ set_link_status (NMDeviceWimax *self, WIMAX_API_LINK_STATUS_INFO_EX *link_status conv_rssi = sdk_rssi_to_dbm (link_status->RSSI); conv_cinr = sdk_cinr_to_db (link_status->CINR); conv_tx_pow = sdk_tx_pow_to_dbm (link_status->txPWR); - new_bsid = nm_utils_hwaddr_ntoa_len (link_status->bsId, 6); + new_bsid = nm_utils_hwaddr_ntoa (link_status->bsId, 6); } if (priv->center_freq != center_freq) { @@ -1363,58 +1347,52 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_NSPS, - g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, - "Network access points", - "Network access points", + g_param_spec_boxed (NM_DEVICE_WIMAX_NSPS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_ACTIVE_NSP, - g_param_spec_boxed (NM_DEVICE_WIMAX_ACTIVE_NSP, - "Active NSP", - "Currently active NSP", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_ACTIVE_NSP, + g_param_spec_boxed (NM_DEVICE_WIMAX_ACTIVE_NSP, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CENTER_FREQ, - g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, - "Center frequency", - "Center frequency", + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, "", "", 0, G_MAXUINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RSSI, - g_param_spec_int (NM_DEVICE_WIMAX_RSSI, - "RSSI", - "RSSI", + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CINR, - g_param_spec_int (NM_DEVICE_WIMAX_CINR, - "CINR", - "CINR", + g_param_spec_int (NM_DEVICE_WIMAX_CINR, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TX_POWER, - g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, - "TX Power", - "TX Power", + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, "", "", G_MININT, G_MAXINT, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_BSID, - g_param_spec_string (NM_DEVICE_WIMAX_BSID, - "BSID", - "BSID", + g_param_spec_string (NM_DEVICE_WIMAX_BSID, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[NSP_ADDED] = @@ -1440,6 +1418,4 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), &dbus_glib_nm_device_wimax_object_info); - - dbus_g_error_domain_register (NM_WIMAX_ERROR, NULL, NM_TYPE_WIMAX_ERROR); } diff --git a/src/devices/wimax/nm-device-wimax.h b/src/devices/wimax/nm-device-wimax.h index 8b252ee1..30b2481f 100644 --- a/src/devices/wimax/nm-device-wimax.h +++ b/src/devices/wimax/nm-device-wimax.h @@ -19,10 +19,9 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_DEVICE_WIMAX_H -#define NM_DEVICE_WIMAX_H +#ifndef __NETWORKMANAGER_DEVICE_WIMAX_H__ +#define __NETWORKMANAGER_DEVICE_WIMAX_H__ -#include #include "nm-device.h" #include "nm-wimax-nsp.h" @@ -35,14 +34,6 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX)) #define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) -typedef enum -{ - NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0, /*< nick=ConnectionNotWimax >*/ - NM_WIMAX_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_WIMAX_ERROR_NSP_NOT_FOUND, /*< nick=NspNotFound >*/ -} NMWimaxError; - #define NM_DEVICE_WIMAX_NSPS "nsps" #define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" #define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" diff --git a/src/devices/wimax/nm-wimax-factory.c b/src/devices/wimax/nm-wimax-factory.c index ca962e68..39e9a287 100644 --- a/src/devices/wimax/nm-wimax-factory.c +++ b/src/devices/wimax/nm-wimax-factory.c @@ -18,10 +18,13 @@ * Copyright (C) 2011 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include "nm-device-factory.h" #include "nm-device-wimax.h" +#include "nm-platform.h" #define NM_TYPE_WIMAX_FACTORY (nm_wimax_factory_get_type ()) #define NM_WIMAX_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_WIMAX_FACTORY, NMWimaxFactory)) @@ -43,20 +46,12 @@ G_DEFINE_TYPE_EXTENDED (NMWimaxFactory, nm_wimax_factory, G_TYPE_OBJECT, 0, /**************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_WIMAX - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WIMAX_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /**************************************************************************/ static NMDevice * @@ -71,10 +66,17 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error) return (NMDevice *) nm_device_wimax_new (plink); } +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_WIMAX; +} + static void device_factory_interface_init (NMDeviceFactory *factory_iface) { factory_iface->new_link = new_link; + factory_iface->get_device_type = get_device_type; } static void diff --git a/src/devices/wimax/nm-wimax-nsp.c b/src/devices/wimax/nm-wimax-nsp.c index efe3b058..f4db63f0 100644 --- a/src/devices/wimax/nm-wimax-nsp.c +++ b/src/devices/wimax/nm-wimax-nsp.c @@ -19,8 +19,10 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include "nm-wimax-nsp.h" -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-setting-wimax.h" #include "nm-wimax-nsp-glue.h" @@ -210,31 +212,28 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *klass) g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string (NM_WIMAX_NSP_NAME, - "Name", - "Name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_string (NM_WIMAX_NSP_NAME, "", "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIGNAL_QUALITY, - g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, - "SignalQuality", - "SignalQuality", - 0, - 100, - 0, - G_PARAM_READWRITE)); + g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, "", "", + 0, + 100, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NETWORK_TYPE, - g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, - "NetworkType", - "NetworkType", + g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE, "", "", NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER, NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (klass), diff --git a/src/devices/wimax/nm-wimax-nsp.h b/src/devices/wimax/nm-wimax-nsp.h index a74b68a7..8d0a6a14 100644 --- a/src/devices/wimax/nm-wimax-nsp.h +++ b/src/devices/wimax/nm-wimax-nsp.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_NSP_H -#define NM_WIMAX_NSP_H +#ifndef __NETWORKMANAGER_WIMAX_NSP_H__ +#define __NETWORKMANAGER_WIMAX_NSP_H__ #include #include "nm-wimax-types.h" diff --git a/src/devices/wimax/nm-wimax-types.h b/src/devices/wimax/nm-wimax-types.h index 8c807fd8..207d2477 100644 --- a/src/devices/wimax/nm-wimax-types.h +++ b/src/devices/wimax/nm-wimax-types.h @@ -18,8 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_TYPES_H -#define NM_WIMAX_TYPES_H +#ifndef __NETWORKMANAGER_WIMAX_TYPES_H__ +#define __NETWORKMANAGER_WIMAX_TYPES_H__ typedef enum { NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN, diff --git a/src/devices/wimax/nm-wimax-util.c b/src/devices/wimax/nm-wimax-util.c index bca25a1d..0ae285ae 100644 --- a/src/devices/wimax/nm-wimax-util.c +++ b/src/devices/wimax/nm-wimax-util.c @@ -18,7 +18,8 @@ * Copyright (C) 2009 Novell, Inc. */ -#include +#include "config.h" + #include "nm-wimax-util.h" #include "nm-utils.h" #include "iwmxsdk.h" diff --git a/src/devices/wimax/nm-wimax-util.h b/src/devices/wimax/nm-wimax-util.h index 71f5aa29..a1852d55 100644 --- a/src/devices/wimax/nm-wimax-util.h +++ b/src/devices/wimax/nm-wimax-util.h @@ -18,12 +18,17 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_WIMAX_UTIL_H -#define NM_WIMAX_UTIL_H +#ifndef __NETWORKMANAGER_WIMAX_UTIL_H__ +#define __NETWORKMANAGER_WIMAX_UTIL_H__ #include +#include "nm-utils-internal.h" + +NM_PRAGMA_WARNING_DISABLE("-Wstrict-prototypes") #include +NM_PRAGMA_WARNING_REENABLE + #include #include "nm-wimax-types.h" diff --git a/src/devices/wwan/Makefile.am b/src/devices/wwan/Makefile.am index 988f4679..7e5b190b 100644 --- a/src/devices/wwan/Makefile.am +++ b/src/devices/wwan/Makefile.am @@ -5,18 +5,16 @@ include $(GLIB_MAKEFILE) AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) @@ -33,9 +31,8 @@ nm_modem_enum_types_sources = $(srcdir)/nm-modem.h BUILT_SOURCES += $(GLIB_GENERATED) libnm_wwan_la_SOURCES = \ - nm-modem-old.c \ - nm-modem-old.h \ - nm-modem-old-types.h \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ nm-modem-manager.c \ nm-modem-manager.h \ nm-modem.c \ @@ -43,12 +40,6 @@ libnm_wwan_la_SOURCES = \ \ $(GLIB_GENERATED) -if WITH_MODEM_MANAGER_1 -libnm_wwan_la_SOURCES += \ - nm-modem-broadband.c \ - nm-modem-broadband.h -endif - WWAN_SYMBOL_VIS_FILE=$(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ diff --git a/src/devices/wwan/Makefile.in b/src/devices/wwan/Makefile.in index ae33d1c8..18cbfdd3 100644 --- a/src/devices/wwan/Makefile.in +++ b/src/devices/wwan/Makefile.in @@ -78,13 +78,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@WITH_MODEM_MANAGER_1_TRUE@am__append_1 = \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.c \ -@WITH_MODEM_MANAGER_1_TRUE@ nm-modem-broadband.h - subdir = src/devices/wwan DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp README + $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ $(top_srcdir)/m4/compiler_warnings.m4 \ @@ -151,15 +147,9 @@ libnm_device_plugin_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(LDFLAGS) -o $@ libnm_wwan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) -am__libnm_wwan_la_SOURCES_DIST = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h nm-modem-enum-types.h \ - nm-modem-enum-types.c nm-modem-broadband.c \ - nm-modem-broadband.h am__objects_1 = nm-modem-enum-types.lo -@WITH_MODEM_MANAGER_1_TRUE@am__objects_2 = nm-modem-broadband.lo -am_libnm_wwan_la_OBJECTS = nm-modem-old.lo nm-modem-manager.lo \ - nm-modem.lo $(am__objects_1) $(am__objects_2) +am_libnm_wwan_la_OBJECTS = nm-modem-broadband.lo nm-modem-manager.lo \ + nm-modem.lo $(am__objects_1) libnm_wwan_la_OBJECTS = $(am_libnm_wwan_la_OBJECTS) libnm_wwan_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -201,7 +191,7 @@ am__v_CCLD_1 = SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ $(libnm_wwan_la_SOURCES) DIST_SOURCES = $(libnm_device_plugin_wwan_la_SOURCES) \ - $(am__libnm_wwan_la_SOURCES_DIST) + $(libnm_wwan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -236,6 +226,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -359,6 +351,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -378,6 +371,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -404,7 +398,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -486,18 +480,16 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/devices \ -I${top_srcdir}/src/settings \ -I${top_srcdir}/src/platform \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ - -I${top_builddir}/libnm-util \ - -I${top_srcdir}/libnm-util \ + -I${top_builddir}/libnm-core \ + -I${top_srcdir}/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-wwan"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(MM_GLIB_CFLAGS) BUILT_SOURCES = $(null) $(GLIB_GENERATED) nm-device-modem-glue.h @@ -508,9 +500,16 @@ GLIB_GENERATED = nm-modem-enum-types.h nm-modem-enum-types.c GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM nm_modem_enum_types_sources = $(srcdir)/nm-modem.h -libnm_wwan_la_SOURCES = nm-modem-old.c nm-modem-old.h \ - nm-modem-old-types.h nm-modem-manager.c nm-modem-manager.h \ - nm-modem.c nm-modem.h $(GLIB_GENERATED) $(am__append_1) +libnm_wwan_la_SOURCES = \ + nm-modem-broadband.c \ + nm-modem-broadband.h \ + nm-modem-manager.c \ + nm-modem-manager.h \ + nm-modem.c \ + nm-modem.h \ + \ + $(GLIB_GENERATED) + WWAN_SYMBOL_VIS_FILE = $(srcdir)/wwan-exports.ver libnm_wwan_la_LDFLAGS = \ -avoid-version \ @@ -624,7 +623,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-broadband.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-enum-types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem-old.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-modem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-wwan-factory.Plo@am__quote@ diff --git a/src/devices/wwan/README b/src/devices/wwan/README deleted file mode 100644 index 4661c042..00000000 --- a/src/devices/wwan/README +++ /dev/null @@ -1,45 +0,0 @@ - -ModemManager integration is organized as follows: - - -Common source -******************************************************************************** - - * nm-modem.[h|c]: - Defines the basic `NMModem' object. The core NetworkManager implementation - will use this interface exclusively, regardless of the real final type of - the modem object. - - * nm-modem-manager.[h|c]: - Defines the `NMModemManager' object, which takes care of listening to - signals from the DBus interface notifying about added or removed modems. - It also takes care of creating proper `NMModem' objects from the - information retrieved from the DBus interface. - - -ModemManager 0.7 integration -******************************************************************************** - - * nm-modem-broadband.[h|c]: - Defines the `NMModemBroadband' object, which is a subclass of `NMModem'. - This object handles both 3GPP and 3GPP2 modems exposed in the new - `ModemManager1' interface. - - -ModemManager 0.4/0.5/0.6 integration -******************************************************************************** - - * nm-modem-old-types.h: - Defines helper types to use with the (old) ModemManager DBus API. - - * nm-modem-old.[h|c]: - Defines the `NMModemGeneric' object. All modem objects based on the old - ModemManager interface are subclasses of this one. - - * nm-modem-gsm.[h|c]: - Defines the `NMModemGsm' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP-specific (GSM, UMTS, HSPA, LTE) modems. - - * nm-modem-cdma.[h|c]: - Defines the `NMModemCdma' object, which is a subclass of `NMModemGeneric'. - This object handles 3GPP2-specific modems (CDMA, EV-DO). diff --git a/src/devices/wwan/exports.ver b/src/devices/wwan/exports.ver index d2c45124..24cd848c 100644 --- a/src/devices/wwan/exports.ver +++ b/src/devices/wwan/exports.ver @@ -1,7 +1,6 @@ { global: nm_device_factory_create; - nm_device_factory_get_device_type; local: *; }; diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 678f7795..f681e59c 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -20,20 +20,22 @@ #include "config.h" +#include #include #include "nm-device-modem.h" #include "nm-modem.h" -#include "nm-modem-old.h" #include "nm-device-private.h" #include "nm-rfkill-manager.h" #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-settings-connection.h" - -#if WITH_MODEM_MANAGER_1 #include "nm-modem-broadband.h" -#endif +#include "NetworkManagerUtils.h" +#include "nm-core-internal.h" + +#include "nm-device-logging.h" +_LOG_DECLARE_SELF(NMDeviceModem); G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE) @@ -91,7 +93,8 @@ modem_prepare_result (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); NMDeviceState state; state = nm_device_get_state (device); @@ -106,8 +109,7 @@ modem_prepare_result (NMModem *modem, * the SIM if the incorrect PIN continues to be used. */ g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL); - nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN", - nm_device_get_iface (device)); + _LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN"); } nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); @@ -147,33 +149,110 @@ modem_auth_result (NMModem *modem, GError *error, gpointer user_data) } static void -modem_ip4_config_result (NMModem *self, +modem_ip4_config_result (NMModem *modem, NMIP4Config *config, GError *error, gpointer user_data) { - NMDevice *device = NM_DEVICE (user_data); + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE); if (error) { - nm_log_warn (LOGD_MB | LOGD_IP4, "retrieving IP4 configuration failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + _LOGW (LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else - nm_device_activate_schedule_ip4_config_result (device, config); + } else { + nm_device_set_wwan_ip4_config (device, config); + nm_device_activate_schedule_ip4_config_result (device, NULL); + } +} + +static void +modem_ip6_config_result (NMModem *modem, + NMIP6Config *config, + gboolean do_slaac, + GError *error, + gpointer user_data) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (user_data); + NMDevice *device = NM_DEVICE (self); + NMActStageReturn ret; + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; + NMIP6Config *ignored = NULL; + gboolean got_config = !!config; + + g_return_if_fail (nm_device_activate_ip6_state_in_conf (device) == TRUE); + + if (error) { + _LOGW (LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); + + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); + return; + } + + /* Re-enable IPv6 on the interface */ + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "0"); + + if (config) + nm_device_set_wwan_ip6_config (device, config); + + if (do_slaac == FALSE) { + if (got_config) + 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); + } + return; + } + + /* Start SLAAC now that we have a link-local address from the modem */ + ret = NM_DEVICE_CLASS (nm_device_modem_parent_class)->act_stage3_ip6_config_start (device, &ignored, &reason); + g_assert (ignored == NULL); + switch (ret) { + case NM_ACT_STAGE_RETURN_FAILURE: + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + break; + case NM_ACT_STAGE_RETURN_STOP: + /* all done */ + nm_device_activate_schedule_ip6_config_result (device); + break; + case NM_ACT_STAGE_RETURN_POSTPONE: + /* let SLAAC run */ + break; + default: + /* Should never get here since we've assured that the IPv6 method + * will either be "auto" or "ignored" when starting IPv6 configuration. + */ + g_assert_not_reached (); + } } static void data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); + const char *old = nm_device_get_ip_iface (self); + const char *new = nm_modem_get_data_port (modem); + gboolean changed = FALSE; + + if (new && g_strcmp0 (new, old)) + changed = TRUE; /* We set the IP iface in the device as soon as we know it, so that we * properly ifup it if needed */ - nm_device_set_ip_iface (self, nm_modem_get_data_port (modem)); + nm_device_set_ip_iface (self, new); + + /* Disable IPv6 immediately on the interface since NM handles IPv6 + * internally, and leaving it enabled could allow the kernel's IPv6 + * RA handling code to run before NM is ready. + */ + if (changed) + nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); } static void @@ -258,6 +337,7 @@ device_state_changed (NMDevice *device, NMDeviceState old_state, NMDeviceStateReason reason) { + NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMConnection *connection = nm_device_get_connection (device); @@ -266,9 +346,8 @@ device_state_changed (NMDevice *device, if (new_state == NM_DEVICE_STATE_UNAVAILABLE && old_state < NM_DEVICE_STATE_UNAVAILABLE) { /* Log initial modem state */ - nm_log_info (LOGD_MB, "(%s): modem state '%s'", - nm_device_get_iface (device), - nm_modem_state_to_string (nm_modem_get_state (priv->modem))); + _LOGI (LOGD_MB, "modem state '%s'", + nm_modem_state_to_string (nm_modem_get_state (priv->modem))); } nm_modem_device_state_changed (priv->modem, new_state, old_state, reason); @@ -294,10 +373,10 @@ device_state_changed (NMDevice *device, } } -static guint -get_hw_address_length (NMDevice *device, gboolean *out_permanent) +static guint32 +get_generic_capabilities (NMDevice *device) { - return 0; + return NM_DEVICE_CAP_IS_NON_KERNEL; } static gboolean @@ -404,11 +483,24 @@ act_stage3_ip6_config_start (NMDevice *device, NMDeviceStateReason *reason) { return nm_modem_stage3_ip6_config_start (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, - device, - NM_DEVICE_CLASS (nm_device_modem_parent_class), + nm_device_get_act_request (device), reason); } +static gboolean +get_ip_iface_identifier (NMDevice *device, NMUtilsIPv6IfaceId *out_iid) +{ + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); + gboolean success; + + g_return_val_if_fail (priv->modem, FALSE); + success = nm_modem_get_iid (priv->modem, out_iid); + if (!success) + success = NM_DEVICE_CLASS (nm_device_modem_parent_class)->get_ip_iface_identifier (device, out_iid); + return success; +} + /*****************************************************************************/ static gboolean @@ -444,23 +536,22 @@ set_enabled (NMDevice *device, gboolean enabled) } static gboolean -is_available (NMDevice *dev) +is_available (NMDevice *device) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (dev); + NMDeviceModem *self = NM_DEVICE_MODEM (device); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); NMModemState modem_state; if (!priv->rf_enabled) { - nm_log_dbg (LOGD_MB, "(%s): not available because WWAN airplane mode is on", - nm_device_get_iface (dev)); + _LOGD (LOGD_MB, "not available because WWAN airplane mode is on"); return FALSE; } g_assert (priv->modem); modem_state = nm_modem_get_state (priv->modem); if (modem_state <= NM_MODEM_STATE_INITIALIZING) { - nm_log_dbg (LOGD_MB, "(%s): not available because modem is not ready (%s)", - nm_device_get_iface (dev), - nm_modem_state_to_string (modem_state)); + _LOGD (LOGD_MB, "not available because modem is not ready (%s)", + nm_modem_state_to_string (modem_state)); return FALSE; } @@ -496,8 +587,10 @@ nm_device_modem_new (NMModem *modem) /* If the data port is known, set it as the IP interface immediately */ data_port = nm_modem_get_data_port (modem); - if (data_port) + if (data_port) { nm_device_set_ip_iface (device, data_port); + nm_device_ipv6_sysctl_set (device, "disable_ipv6", "1"); + } return device; } @@ -507,6 +600,18 @@ nm_device_modem_init (NMDeviceModem *self) { } +static void +constructed (GObject *object) +{ + G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object); + + /* DHCP is always done by the modem firmware, not by the network, and + * by the time we get around to DHCP the firmware should already know + * the IP addressing details. So the DHCP timeout can be much shorter. + */ + nm_device_set_dhcp_timeout (NM_DEVICE (object), 15); +} + static void set_modem (NMDeviceModem *self, NMModem *modem) { @@ -519,6 +624,7 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); + g_signal_connect (modem, NM_MODEM_IP6_CONFIG_RESULT, G_CALLBACK (modem_ip6_config_result), self); g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self); @@ -599,8 +705,9 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; + object_class->constructed = constructed; - device_class->get_hw_address_length = get_hw_address_length; + device_class->get_generic_capabilities = get_generic_capabilities; device_class->check_connection_compatible = check_connection_compatible; device_class->check_connection_available = check_connection_available; device_class->complete_connection = complete_connection; @@ -614,31 +721,31 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->set_enabled = set_enabled; device_class->owns_iface = owns_iface; device_class->is_available = is_available; + device_class->get_ip_iface_identifier = get_ip_iface_identifier; device_class->state_changed = device_state_changed; /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_DEVICE_MODEM_MODEM, - "Modem", - "Modem", + g_param_spec_object (NM_DEVICE_MODEM_MODEM, "", "", NM_TYPE_MODEM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, - "Modem Capabilities", - "Modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_CURRENT_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, - "Current modem Capabilities", - "Current modem Capabilities", - 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_CURRENT_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES, "", "", + 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (mclass), diff --git a/src/devices/wwan/nm-device-modem.h b/src/devices/wwan/nm-device-modem.h index ee6b2988..996195c4 100644 --- a/src/devices/wwan/nm-device-modem.h +++ b/src/devices/wwan/nm-device-modem.h @@ -18,8 +18,8 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#ifndef NM_DEVICE_MODEM_H -#define NM_DEVICE_MODEM_H +#ifndef __NETWORKMANAGER_DEVICE_MODEM_H__ +#define __NETWORKMANAGER_DEVICE_MODEM_H__ #include #include @@ -51,4 +51,4 @@ GType nm_device_modem_get_type (void); NMDevice *nm_device_modem_new (NMModem *modem); -#endif /* NM_DEVICE_MODEM_H */ +#endif /* __NETWORKMANAGER_DEVICE_MODEM_H__ */ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 807b8924..f8239b79 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -18,14 +18,19 @@ * Copyright (C) 2012 Aleksander Morgado */ +#include "config.h" + #include #include +#include #include + #include "nm-modem-broadband.h" -#include "nm-setting-connection.h" +#include "nm-core-internal.h" #include "nm-logging.h" #include "NetworkManagerUtils.h" #include "nm-device-private.h" +#include "nm-platform.h" G_DEFINE_TYPE (NMModemBroadband, nm_modem_broadband, NM_TYPE_MODEM) @@ -156,13 +161,29 @@ ask_for_pin (NMModemBroadband *self) NM_SETTING_GSM_PIN); } +static NMModemIPMethod +get_bearer_ip_method (MMBearerIpConfig *config) +{ + MMBearerIpMethod mm_method; + + mm_method = mm_bearer_ip_config_get_method (config); + if (mm_method == MM_BEARER_IP_METHOD_PPP) + return NM_MODEM_IP_METHOD_PPP; + else if (mm_method == MM_BEARER_IP_METHOD_STATIC) + return NM_MODEM_IP_METHOD_STATIC; + else if (mm_method == MM_BEARER_IP_METHOD_DHCP) + return NM_MODEM_IP_METHOD_AUTO; + return NM_MODEM_IP_METHOD_UNKNOWN; +} + static void connect_ready (MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { GError *error = NULL; - guint ip_method; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_clear_object (&self->priv->connect_properties); @@ -195,35 +216,31 @@ connect_ready (MMModemSimple *simple_iface, /* Grab IP configurations */ self->priv->ipv4_config = mm_bearer_get_ipv4_config (self->priv->bearer); - self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv4_config) + ip4_method = get_bearer_ip_method (self->priv->ipv4_config); - switch (mm_bearer_ip_config_get_method (self->priv->ipv4_config)) { - case MM_BEARER_IP_METHOD_PPP: - ip_method = MM_MODEM_IP_METHOD_PPP; - break; - case MM_BEARER_IP_METHOD_STATIC: - ip_method = MM_MODEM_IP_METHOD_STATIC; - break; - case MM_BEARER_IP_METHOD_DHCP: - ip_method = MM_MODEM_IP_METHOD_DHCP; - break; - default: - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, - "invalid IP config"); - nm_log_warn (LOGD_MB, "(%s) failed to connect modem: %s", - nm_modem_get_uid (NM_MODEM (self)), - error->message); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); + self->priv->ipv6_config = mm_bearer_get_ipv6_config (self->priv->bearer); + if (self->priv->ipv6_config) + ip6_method = get_bearer_ip_method (self->priv->ipv6_config); + + 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))); + + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "invalid bearer IP configuration"); + g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, error); g_error_free (error); g_object_unref (self); return; } - /* IPv4 for now only */ g_object_set (self, NM_MODEM_DATA_PORT, mm_bearer_get_interface (self->priv->bearer), - NM_MODEM_IP_METHOD, ip_method, + NM_MODEM_IP4_METHOD, ip4_method, + NM_MODEM_IP6_METHOD, ip6_method, NM_MODEM_IP_TIMEOUT, mm_bearer_get_ip_timeout (self->priv->bearer), NULL); @@ -249,12 +266,15 @@ create_cdma_connect_properties (NMConnection *connection) } static MMSimpleConnectProperties * -create_gsm_connect_properties (NMConnection *connection) +create_gsm_connect_properties (NMModem *modem, + NMConnection *connection, + GError **error) { NMSettingGsm *setting; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; MMSimpleConnectProperties *properties; const gchar *str; + NMModemIPType ip_type; setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); @@ -264,9 +284,9 @@ create_gsm_connect_properties (NMConnection *connection) if (str) mm_simple_connect_properties_set_number (properties, str); + /* Blank APN ("") means the default subscription APN */ str = nm_setting_gsm_get_apn (setting); - if (str) - mm_simple_connect_properties_set_apn (properties, str); + mm_simple_connect_properties_set_apn (properties, str ? str : ""); str = nm_setting_gsm_get_network_id (setting); if (str) @@ -309,6 +329,22 @@ create_gsm_connect_properties (NMConnection *connection) mm_simple_connect_properties_set_allowed_auth (properties, allowed_auth); } + /* Determine IP types to use when connecting */ + ip_type = nm_modem_get_connection_ip_type (modem, connection, error); + if (ip_type == NM_MODEM_IP_TYPE_UNKNOWN) { + g_object_unref (properties); + return NULL; + } + + if (ip_type == NM_MODEM_IP_TYPE_IPV4) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4); + else if (ip_type == NM_MODEM_IP_TYPE_IPV6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV6); + else if (ip_type == NM_MODEM_IP_TYPE_IPV4V6) + mm_simple_connect_properties_set_ip_type (properties, MM_BEARER_IP_FAMILY_IPV4V6); + else + g_assert_not_reached (); + return properties; } @@ -319,17 +355,29 @@ act_stage1_prepare (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability caps; + GError *error = NULL; g_clear_object (&self->priv->connect_properties); caps = mm_modem_get_current_capabilities (self->priv->modem_iface); if (MODEM_CAPS_3GPP (caps)) - self->priv->connect_properties = create_gsm_connect_properties (connection); + self->priv->connect_properties = create_gsm_connect_properties (_self, connection, &error); else if (MODEM_CAPS_3GPP2 (caps)) self->priv->connect_properties = create_cdma_connect_properties (connection); else { nm_log_warn (LOGD_MB, "(%s) not a mobile broadband modem", nm_modem_get_uid (NM_MODEM (self))); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + if (error) { + nm_log_warn (LOGD_MB, "(%s): Failed to connect '%s': %s", + nm_modem_get_uid (NM_MODEM (self)), + nm_connection_get_id (connection), + error->message); + g_clear_error (&error); + *reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -400,14 +448,14 @@ complete_connection (NMModem *_self, { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability modem_caps; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; modem_caps = mm_modem_get_current_capabilities (self->priv->modem_iface); /* PPP settings common to 3GPP and 3GPP2 */ s_ppp = nm_connection_get_setting_ppp (connection); if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); g_object_set (G_OBJECT (s_ppp), NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, @@ -419,12 +467,13 @@ complete_connection (NMModem *_self, NMSettingGsm *s_gsm; s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ + if (!s_gsm) { + /* Need a GSM setting at least */ g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("GSM mobile broadband connection requires a 'gsm' setting")); + g_prefix_error (error, "%s: ", NM_SETTING_GSM_SETTING_NAME); return FALSE; } @@ -435,7 +484,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_GSM_SETTING_NAME, existing_connections, - _("GSM connection %d"), + NULL, + _("GSM connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -457,7 +507,8 @@ complete_connection (NMModem *_self, nm_utils_complete_generic (connection, NM_SETTING_CDMA_SETTING_NAME, existing_connections, - _("CDMA connection %d"), + NULL, + _("CDMA connection"), NULL, FALSE); /* No IPv6 yet by default */ @@ -465,8 +516,8 @@ complete_connection (NMModem *_self, } g_set_error (error, - NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, "Device is not a mobile broadband modem"); return FALSE; } @@ -590,11 +641,10 @@ set_mm_enabled (NMModem *_self, } /*****************************************************************************/ -/* IP method static */ +/* IPv4 method static */ static gboolean -ip_string_to_network_address (const gchar *str, - guint32 *out) +ip4_string_to_num (const gchar *str, guint32 *out) { guint32 addr = 0; gboolean success = FALSE; @@ -609,7 +659,7 @@ ip_string_to_network_address (const gchar *str, } static gboolean -static_stage3_done (NMModemBroadband *self) +static_stage3_ip4_done (NMModemBroadband *self) { GError *error = NULL; NMIP4Config *config = NULL; @@ -628,9 +678,9 @@ static_stage3_done (NMModemBroadband *self) /* Fully fail if invalid IP address retrieved */ address_string = mm_bearer_ip_config_get_address (self->priv->ipv4_config); - if (!ip_string_to_network_address (address_string, &address_network)) { - error = g_error_new (NM_MODEM_ERROR, - NM_MODEM_ERROR_CONNECTION_INVALID, + if (!ip4_string_to_num (address_string, &address_network)) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, "(%s) retrieving IP4 configuration failed: invalid address given '%s'", nm_modem_get_uid (NM_MODEM (self)), address_string); @@ -639,14 +689,14 @@ static_stage3_done (NMModemBroadband *self) /* Missing gateway not a hard failure */ gw_string = mm_bearer_ip_config_get_gateway (self->priv->ipv4_config); - ip_string_to_network_address (gw_string, &gw); + ip4_string_to_num (gw_string, &gw); config = nm_ip4_config_new (); memset (&address, 0, sizeof (address)); address.address = address_network; address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv4_config); - address.source = NM_PLATFORM_SOURCE_WWAN; + address.source = NM_IP_CONFIG_SOURCE_WWAN; nm_ip4_config_add_address (config, &address); nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); @@ -659,7 +709,7 @@ static_stage3_done (NMModemBroadband *self) /* DNS servers */ dns = mm_bearer_ip_config_get_dns (self->priv->ipv4_config); for (i = 0; dns[i]; i++) { - if ( ip_string_to_network_address (dns[i], &address_network) + 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]); @@ -681,7 +731,110 @@ static_stage3_ip4_config_start (NMModem *_self, /* We schedule it in an idle just to follow the same logic as in the * generic modem implementation. */ - g_idle_add ((GSourceFunc)static_stage3_done, self); + g_idle_add ((GSourceFunc) static_stage3_ip4_done, self); + + return NM_ACT_STAGE_RETURN_POSTPONE; +} + +/*****************************************************************************/ +/* IPv6 method static */ + +static gboolean +stage3_ip6_done (NMModemBroadband *self) +{ + GError *error = NULL; + NMIP6Config *config = NULL; + const gchar *address_string; + NMPlatformIP6Address address; + NMModemIPMethod ip_method; + const gchar **dns; + guint i; + + g_assert (self->priv->ipv6_config); + + memset (&address, 0, sizeof (address)); + + ip_method = get_bearer_ip_method (self->priv->ipv6_config); + + address_string = mm_bearer_ip_config_get_address (self->priv->ipv6_config); + if (!address_string) { + /* DHCP/SLAAC is allowed to skip addresses; other methods require it */ + if (ip_method != NM_MODEM_IP_METHOD_AUTO) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: no address given", + nm_modem_get_uid (NM_MODEM (self))); + } + goto out; + } + + /* Fail if invalid IP address retrieved */ + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid address given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + + nm_log_info (LOGD_MB, "(%s): IPv6 base configuration:", + nm_modem_get_uid (NM_MODEM (self))); + + config = nm_ip6_config_new (); + + address.plen = mm_bearer_ip_config_get_prefix (self->priv->ipv6_config); + nm_ip6_config_add_address (config, &address); + + nm_log_info (LOGD_MB, " address %s/%d", address_string, address.plen); + + address_string = mm_bearer_ip_config_get_gateway (self->priv->ipv6_config); + if (address_string) { + if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) { + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'", + nm_modem_get_uid (NM_MODEM (self)), + address_string); + goto out; + } + nm_log_info (LOGD_MB, " 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 */ + error = g_error_new (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INVALID_CONNECTION, + "(%s) retrieving IPv6 configuration failed: missing gateway", + nm_modem_get_uid (NM_MODEM (self))); + goto out; + } + + /* DNS servers */ + dns = mm_bearer_ip_config_get_dns (self->priv->ipv6_config); + for (i = 0; dns[i]; i++) { + struct in6_addr addr; + + if (inet_pton (AF_INET6, dns[i], &addr)) { + nm_ip6_config_add_nameserver (config, &addr); + nm_log_info (LOGD_MB, " DNS %s", dns[i]); + } + } + +out: + nm_modem_emit_ip6_config_result (NM_MODEM (self), config, error); + g_clear_object (&config); + g_clear_error (&error); + return FALSE; +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *_self, NMDeviceStateReason *reason) +{ + NMModemBroadband *self = NM_MODEM_BROADBAND (_self); + + /* We schedule it in an idle just to follow the same logic as in the + * generic modem implementation. */ + g_idle_add ((GSourceFunc) stage3_ip6_done, self); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -720,11 +873,15 @@ simple_disconnect_ready (MMModemSimple *modem_iface, } static void -disconnect (NMModem *self, +disconnect (NMModem *modem, gboolean warn) { + NMModemBroadband *self = NM_MODEM_BROADBAND (modem); SimpleDisconnectContext *ctx; + if (!self->priv->simple_iface) + return; + ctx = g_slice_new (SimpleDisconnectContext); ctx->self = g_object_ref (self); @@ -806,6 +963,21 @@ modem_state_changed (MMModem *modem, /*****************************************************************************/ +static NMModemIPType +mm_ip_family_to_nm (MMBearerIpFamily family) +{ + NMModemIPType nm_type = NM_MODEM_IP_TYPE_UNKNOWN; + + if (family & MM_BEARER_IP_FAMILY_IPV4) + nm_type |= NM_MODEM_IP_TYPE_IPV4; + if (family & MM_BEARER_IP_FAMILY_IPV6) + nm_type |= NM_MODEM_IP_TYPE_IPV6; + if (family & MM_BEARER_IP_FAMILY_IPV4V6) + nm_type |= MM_BEARER_IP_FAMILY_IPV4V6; + + return nm_type; +} + NMModem * nm_modem_broadband_new (GObject *object, GError **error) { @@ -830,6 +1002,7 @@ nm_modem_broadband_new (GObject *object, GError **error) NM_MODEM_UID, mm_modem_get_primary_port (modem_iface), NM_MODEM_CONTROL_PORT, mm_modem_get_primary_port (modem_iface), NM_MODEM_DATA_PORT, NULL, /* We don't know it until bearer created */ + NM_MODEM_IP_TYPES, mm_ip_family_to_nm (mm_modem_get_supported_ip_families (modem_iface)), NM_MODEM_STATE, mm_state_to_nm (mm_modem_get_state (modem_iface)), NM_MODEM_DEVICE_ID, mm_modem_get_device_identifier (modem_iface), NM_MODEM_BROADBAND_MODEM, modem_object, @@ -967,6 +1140,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->get_capabilities = get_capabilities; modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; + modem_class->stage3_ip6_config_request = stage3_ip6_config_request; modem_class->disconnect = disconnect; modem_class->deactivate = deactivate; modem_class->set_mm_enabled = set_mm_enabled; @@ -979,9 +1153,8 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) /* Properties */ g_object_class_install_property (object_class, PROP_MODEM, - g_param_spec_object (NM_MODEM_BROADBAND_MODEM, - "Modem", - "Broadband modem object", + g_param_spec_object (NM_MODEM_BROADBAND_MODEM, "", "", MM_GDBUS_TYPE_OBJECT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/devices/wwan/nm-modem-broadband.h b/src/devices/wwan/nm-modem-broadband.h index e12ca68c..2268bac4 100644 --- a/src/devices/wwan/nm-modem-broadband.h +++ b/src/devices/wwan/nm-modem-broadband.h @@ -18,10 +18,9 @@ * Copyright (C) 2012 - Aleksander Morgado */ -#ifndef NM_MODEM_BROADBAND_H -#define NM_MODEM_BROADBAND_H +#ifndef __NETWORKMANAGER_MODEM_BROADBAND_H__ +#define __NETWORKMANAGER_MODEM_BROADBAND_H__ -#include #include #include "nm-modem.h" @@ -55,4 +54,4 @@ NMModem *nm_modem_broadband_new (GObject *object, GError **error); G_END_DECLS -#endif /* NM_MODEM_BROADBAND_H */ +#endif /* __NETWORKMANAGER_MODEM_BROADBAND_H__ */ diff --git a/src/devices/wwan/nm-modem-enum-types.c b/src/devices/wwan/nm-modem-enum-types.c index cf59ba2b..6fbb3b6d 100644 --- a/src/devices/wwan/nm-modem-enum-types.c +++ b/src/devices/wwan/nm-modem-enum-types.c @@ -8,22 +8,42 @@ #include "nm-modem.h" GType -nm_modem_error_get_type (void) +nm_modem_ip_method_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_MODEM_ERROR_CONNECTION_NOT_GSM, "NM_MODEM_ERROR_CONNECTION_NOT_GSM", "ConnectionNotGsm" }, - { NM_MODEM_ERROR_CONNECTION_NOT_CDMA, "NM_MODEM_ERROR_CONNECTION_NOT_CDMA", "ConnectionNotCdma" }, - { NM_MODEM_ERROR_CONNECTION_INVALID, "NM_MODEM_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, "NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_MODEM_ERROR_INITIALIZATION_FAILED, "NM_MODEM_ERROR_INITIALIZATION_FAILED", "InitializationFailed" }, + { NM_MODEM_IP_METHOD_UNKNOWN, "NM_MODEM_IP_METHOD_UNKNOWN", "unknown" }, + { NM_MODEM_IP_METHOD_PPP, "NM_MODEM_IP_METHOD_PPP", "ppp" }, + { NM_MODEM_IP_METHOD_STATIC, "NM_MODEM_IP_METHOD_STATIC", "static" }, + { NM_MODEM_IP_METHOD_AUTO, "NM_MODEM_IP_METHOD_AUTO", "auto" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMModemError"), values); + g_enum_register_static (g_intern_static_string ("NMModemIPMethod"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} +GType +nm_modem_ip_type_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GEnumValue values[] = { + { NM_MODEM_IP_TYPE_UNKNOWN, "NM_MODEM_IP_TYPE_UNKNOWN", "unknown" }, + { NM_MODEM_IP_TYPE_IPV4, "NM_MODEM_IP_TYPE_IPV4", "ipv4" }, + { NM_MODEM_IP_TYPE_IPV6, "NM_MODEM_IP_TYPE_IPV6", "ipv6" }, + { NM_MODEM_IP_TYPE_IPV4V6, "NM_MODEM_IP_TYPE_IPV4V6", "ipv4v6" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("NMModemIPType"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } diff --git a/src/devices/wwan/nm-modem-enum-types.h b/src/devices/wwan/nm-modem-enum-types.h index 81ccd8d2..ccbe6201 100644 --- a/src/devices/wwan/nm-modem-enum-types.h +++ b/src/devices/wwan/nm-modem-enum-types.h @@ -9,8 +9,10 @@ #include G_BEGIN_DECLS -GType nm_modem_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_MODEM_ERROR (nm_modem_error_get_type ()) +GType nm_modem_ip_method_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_METHOD (nm_modem_ip_method_get_type ()) +GType nm_modem_ip_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_MODEM_IP_TYPE (nm_modem_ip_type_get_type ()) GType nm_modem_state_get_type (void) G_GNUC_CONST; #define NM_TYPE_MODEM_STATE (nm_modem_state_get_type ()) G_END_DECLS diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index c4811700..f0e56926 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -20,42 +20,28 @@ * Copyright (C) 2009 Canonical Ltd. */ -#include #include "config.h" + +#include + +#include + #include "nm-modem-manager.h" #include "nm-logging.h" #include "nm-modem.h" -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-modem-old-types.h" -#include "nm-dbus-glib-types.h" - -#if WITH_MODEM_MANAGER_1 -#include #include "nm-modem-broadband.h" -#endif #define MODEM_POKE_INTERVAL 120 G_DEFINE_TYPE (NMModemManager, nm_modem_manager, G_TYPE_OBJECT) struct _NMModemManagerPrivate { - /* ModemManager < 0.7 */ - NMDBusManager *dbus_mgr; - DBusGProxy *proxy; - guint poke_id; - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ GDBusConnection *dbus_connection; - MMManager *modem_manager_1; - guint modem_manager_1_launch_id; - gboolean old_modem_manager_found; - gboolean new_modem_manager_found; - guint modem_manager_1_name_owner_changed_id; - guint modem_manager_1_object_added_id; - guint modem_manager_1_object_removed_id; -#endif + MMManager *modem_manager; + guint mm_launch_id; + guint mm_name_owner_changed_id; + guint mm_object_added_id; + guint mm_object_removed_id; /* Common */ GHashTable *modems; @@ -85,191 +71,6 @@ handle_new_modem (NMModemManager *self, NMModem *modem) g_signal_emit (self, signals[MODEM_ADDED], 0, modem); } -/************************************************************************/ -/* Support for ModemManager < 0.7 */ - -static void -clear_modem_manager_support (NMModemManager *self) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } -} - -static void -create_modem (NMModemManager *self, const char *path) -{ - DBusGProxy *proxy; - GError *error = NULL; - NMModem *modem = NULL; - GHashTable *properties; - - if (g_hash_table_lookup (self->priv->modems, path)) { - nm_log_warn (LOGD_MB, "modem with path %s already exists, ignoring", path); - return; - } - - proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, - path, - DBUS_INTERFACE_PROPERTIES); - g_assert (proxy); - if (dbus_g_proxy_call_with_timeout (proxy, "GetAll", 15000, &error, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM, - G_TYPE_INVALID, - DBUS_TYPE_G_MAP_OF_VARIANT, &properties, - G_TYPE_INVALID)) { - /* Success, create the modem */ - modem = nm_modem_old_new (path, properties, &error); - if (modem) - handle_new_modem (self, modem); - else { - nm_log_warn (LOGD_MB, "failed to create modem: %s", - error ? error->message : "(unknown)"); - } - g_hash_table_destroy (properties); - } else { - nm_log_warn (LOGD_MB, "could not get modem properties: %s %s", - error ? dbus_g_error_get_name (error) : "(none)", - error ? error->message : "(unknown)"); - } - - g_object_unref (proxy); - g_clear_error (&error); -} - -static void -modem_added (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - create_modem (NM_MODEM_MANAGER (user_data), path); -} - -static void -modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - NMModem *modem; - - modem = (NMModem *) g_hash_table_lookup (self->priv->modems, path); - if (modem) { - nm_modem_emit_removed (modem); - g_hash_table_remove (self->priv->modems, path); - } -} - -static void -mm_poke_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - GPtrArray *modems; - int i; - - if (dbus_g_proxy_end_call (proxy, call, NULL, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &modems, - G_TYPE_INVALID)) { - /* Don't care about the returned value, just free it */ - for (i = 0; i < modems->len; i++) - g_free ((char *) g_ptr_array_index (modems, i)); - g_ptr_array_free (modems, TRUE); - } - g_object_unref (proxy); -} - -static gboolean -poke_modem_cb (gpointer user_data) -{ - NMModemManager *self = NM_MODEM_MANAGER (user_data); - DBusGConnection *g_connection; - DBusGProxy *proxy; - - g_connection = nm_dbus_manager_get_connection (self->priv->dbus_mgr); - proxy = dbus_g_proxy_new_for_name (g_connection, - MM_OLD_DBUS_SERVICE, - MM_OLD_DBUS_PATH, - MM_OLD_DBUS_INTERFACE); - - nm_log_dbg (LOGD_MB, "Requesting to (re)launch modem-manager..."); - - dbus_g_proxy_begin_call_with_timeout (proxy, - "EnumerateDevices", - mm_poke_cb, - NULL, - NULL, - 5000, - G_TYPE_INVALID); - return TRUE; -} - -static void -enumerate_devices_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer data) -{ - NMModemManager *manager = NM_MODEM_MANAGER (data); - GPtrArray *modems; - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "could not get modem list: %s", error->message); - g_error_free (error); - } else { - int i; - - for (i = 0; i < modems->len; i++) { - char *path = (char *) g_ptr_array_index (modems, i); - - create_modem (manager, path); - g_free (path); - } - - g_ptr_array_free (modems, TRUE); - } -} - -#if WITH_MODEM_MANAGER_1 -static void clear_modem_manager_1_support (NMModemManager *self); -#endif - -static void -modem_manager_appeared (NMModemManager *self, gboolean enumerate_devices) -{ - if (self->priv->poke_id) { - g_source_remove (self->priv->poke_id); - self->priv->poke_id = 0; - } - - nm_log_info (LOGD_MB, "modem-manager is now available"); - -#if WITH_MODEM_MANAGER_1 - self->priv->old_modem_manager_found = TRUE; - if (self->priv->new_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_1_support (self); -#endif - - self->priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (self->priv->dbus_mgr), - MM_OLD_DBUS_SERVICE, MM_OLD_DBUS_PATH, MM_OLD_DBUS_INTERFACE); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceAdded", - G_CALLBACK (modem_added), self, - NULL); - - dbus_g_proxy_add_signal (self->priv->proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (self->priv->proxy, "DeviceRemoved", - G_CALLBACK (modem_removed), self, - NULL); - - if (enumerate_devices) - dbus_g_proxy_begin_call (self->priv->proxy, "EnumerateDevices", enumerate_devices_done, self, NULL, G_TYPE_INVALID); -} - static gboolean remove_one_modem (gpointer key, gpointer value, gpointer user_data) { @@ -278,93 +79,34 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data) } static void -modem_manager_disappeared (NMModemManager *self) +modem_manager_clear_signals (NMModemManager *self) { - g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, self); - - if (self->priv->proxy) { - g_object_unref (self->priv->proxy); - self->priv->proxy = NULL; - } - - /* Try to activate the modem-manager */ - nm_log_dbg (LOGD_MB, "trying to start the modem manager..."); - poke_modem_cb (self); - self->priv->poke_id = g_timeout_add_seconds (MODEM_POKE_INTERVAL, poke_modem_cb, self); -} - -static void -nm_modem_manager_name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) -{ - gboolean old_owner_good; - gboolean new_owner_good; - - /* Can't handle the signal if its not from the modem service */ - if (strcmp (MM_OLD_DBUS_SERVICE, name) != 0) + if (!self->priv->modem_manager) return; - old_owner_good = (old_owner && strlen (old_owner)); - new_owner_good = (new_owner && strlen (new_owner)); - - if (!old_owner_good && new_owner_good) { - modem_manager_appeared (NM_MODEM_MANAGER (user_data), FALSE); - } else if (old_owner_good && !new_owner_good) { - nm_log_info (LOGD_MB, "the modem manager disappeared"); - modem_manager_disappeared (NM_MODEM_MANAGER (user_data)); - } -} - -/************************************************************************/ -/* Support for ModemManager >= 0.7 */ - -#if WITH_MODEM_MANAGER_1 - -static void -modem_manager_1_clear_signals (NMModemManager *self) -{ - if (!self->priv->modem_manager_1) - return; - - if (self->priv->modem_manager_1_name_owner_changed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_name_owner_changed_id); - self->priv->modem_manager_1_name_owner_changed_id = 0; - } - - if (self->priv->modem_manager_1_object_added_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_added_id); - self->priv->modem_manager_1_object_added_id = 0; + if (self->priv->mm_name_owner_changed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_name_owner_changed_id); + self->priv->mm_name_owner_changed_id = 0; } - if (self->priv->modem_manager_1_object_removed_id) { - if (g_signal_handler_is_connected (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id)) - g_signal_handler_disconnect (self->priv->modem_manager_1, - self->priv->modem_manager_1_object_removed_id); - self->priv->modem_manager_1_object_removed_id = 0; + if (self->priv->mm_object_added_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_added_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_added_id); + self->priv->mm_object_added_id = 0; } -} -static void -clear_modem_manager_1_support (NMModemManager *self) -{ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_object_removed_id) { + if (g_signal_handler_is_connected (self->priv->modem_manager, + self->priv->mm_object_removed_id)) + g_signal_handler_disconnect (self->priv->modem_manager, + self->priv->mm_object_removed_id); + self->priv->mm_object_removed_id = 0; } - - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); - g_clear_object (&self->priv->dbus_connection); } static void @@ -426,49 +168,43 @@ modem_object_removed (MMManager *manager, } static void -modem_manager_1_available (NMModemManager *self) +modem_manager_available (NMModemManager *self) { GList *modems, *l; nm_log_info (LOGD_MB, "ModemManager available in the bus"); - self->priv->new_modem_manager_found = TRUE; - if (self->priv->old_modem_manager_found) - nm_log_warn (LOGD_MB, "Both the old and the new ModemManager were found"); - else - clear_modem_manager_support (self); - /* Update initial modems list */ - modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager_1)); - for (l = modems; l; l = g_list_next (l)) - modem_object_added (self->priv->modem_manager_1, MM_OBJECT (l->data), self); - g_list_free_full (modems, (GDestroyNotify) g_object_unref); + modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (self->priv->modem_manager)); + for (l = modems; l; l = g_list_next (l)) + modem_object_added (self->priv->modem_manager, MM_OBJECT (l->data), self); + g_list_free_full (modems, (GDestroyNotify) g_object_unref); } -static void schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds); -static void ensure_client (NMModemManager *self); +static void schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds); +static void ensure_client (NMModemManager *self); static void -modem_manager_1_name_owner_changed (MMManager *modem_manager_1, - GParamSpec *pspec, - NMModemManager *self) +modem_manager_name_owner_changed (MMManager *modem_manager, + GParamSpec *pspec, + NMModemManager *self) { gchar *name_owner; /* Quit poking, if any */ - if (self->priv->modem_manager_1_launch_id) { - g_source_remove (self->priv->modem_manager_1_launch_id); - self->priv->modem_manager_1_launch_id = 0; + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; } - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (modem_manager)); if (!name_owner) { nm_log_info (LOGD_MB, "ModemManager disappeared from bus"); #if !HAVE_SYSTEMD /* If not managed by systemd, schedule relaunch */ - schedule_modem_manager_1_relaunch (self, 0); + schedule_modem_manager_relaunch (self, 0); #endif return; @@ -481,21 +217,21 @@ modem_manager_1_name_owner_changed (MMManager *modem_manager_1, * nor 'object-removed' if it was created while there was no ModemManager in * the bus. This hack avoids this issue until we get a GIO with the fix * included... */ - modem_manager_1_clear_signals (self); - g_clear_object (&self->priv->modem_manager_1); + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); ensure_client (self); /* Whenever GDBusObjectManagerClient is fixed, we can just do the following: - * modem_manager_1_available (self); + * modem_manager_available (self); */ } #if !HAVE_SYSTEMD static void -modem_manager_1_poke_cb (GDBusConnection *connection, - GAsyncResult *res, - NMModemManager *self) +modem_manager_poke_cb (GDBusConnection *connection, + GAsyncResult *res, + NMModemManager *self) { GError *error = NULL; GVariant *result; @@ -514,7 +250,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else g_variant_unref (result); @@ -523,7 +259,7 @@ modem_manager_1_poke_cb (GDBusConnection *connection, } static void -modem_manager_1_poke (NMModemManager *self) +modem_manager_poke (NMModemManager *self) { /* If there is no current owner right away, ensure we poke to get one */ g_dbus_connection_call (self->priv->dbus_connection, @@ -536,28 +272,28 @@ modem_manager_1_poke (NMModemManager *self) G_DBUS_CALL_FLAGS_NONE, -1, NULL, /* cancellable */ - (GAsyncReadyCallback)modem_manager_1_poke_cb, /* callback */ + (GAsyncReadyCallback)modem_manager_poke_cb, /* callback */ g_object_ref (self)); /* user_data */ } #endif /* HAVE_SYSTEMD */ static void -modem_manager_1_check_name_owner (NMModemManager *self) +modem_manager_check_name_owner (NMModemManager *self) { gchar *name_owner; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager_1)); + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (self->priv->modem_manager)); if (name_owner) { /* Available! */ - modem_manager_1_available (self); + modem_manager_available (self); g_free (name_owner); return; } #if !HAVE_SYSTEMD /* If the lifecycle is not managed by systemd, poke */ - modem_manager_1_poke (self); + modem_manager_poke (self); #endif } @@ -570,38 +306,35 @@ manager_new_ready (GObject *source, GError *error = NULL; - g_assert (!self->priv->modem_manager_1); - self->priv->modem_manager_1 = mm_manager_new_finish (res, &error); - if (!self->priv->modem_manager_1) { + g_assert (!self->priv->modem_manager); + self->priv->modem_manager = mm_manager_new_finish (res, &error); + if (!self->priv->modem_manager) { /* We're not really supposed to get any error here. If we do get one, * though, just re-schedule the MMManager creation after some time. * During this period, name-owner changes won't be followed. */ nm_log_warn (LOGD_MB, "error creating ModemManager client: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Setup signals in the GDBusObjectManagerClient */ - self->priv->modem_manager_1_name_owner_changed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_name_owner_changed_id = + g_signal_connect (self->priv->modem_manager, "notify::name-owner", - G_CALLBACK (modem_manager_1_name_owner_changed), + G_CALLBACK (modem_manager_name_owner_changed), self); - self->priv->modem_manager_1_object_added_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_added_id = + g_signal_connect (self->priv->modem_manager, "object-added", G_CALLBACK (modem_object_added), self); - self->priv->modem_manager_1_object_removed_id = - g_signal_connect (self->priv->modem_manager_1, + self->priv->mm_object_removed_id = + g_signal_connect (self->priv->modem_manager, "object-removed", G_CALLBACK (modem_object_removed), self); - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } /* Balance refcount */ @@ -616,7 +349,7 @@ ensure_client (NMModemManager *self) /* Create the GDBusObjectManagerClient. We do not request to autostart, as * we don't really want the MMManager creation to fail. We can always poke * later on if we want to request the autostart */ - if (!self->priv->modem_manager_1) { + if (!self->priv->modem_manager) { mm_manager_new (self->priv->dbus_connection, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, NULL, @@ -626,7 +359,7 @@ ensure_client (NMModemManager *self) } /* If already available, recheck name owner! */ - modem_manager_1_check_name_owner (self); + modem_manager_check_name_owner (self); } static void @@ -643,10 +376,7 @@ bus_get_ready (GObject *source, nm_log_warn (LOGD_CORE, "error getting bus connection: %s", error->message); g_error_free (error); /* Setup timeout to relaunch */ - schedule_modem_manager_1_relaunch (self, MODEM_POKE_INTERVAL); - } else if (self->priv->old_modem_manager_found) { - /* If we found the old MM, abort */ - clear_modem_manager_1_support (self); + schedule_modem_manager_relaunch (self, MODEM_POKE_INTERVAL); } else { /* Got the bus, ensure client */ ensure_client (self); @@ -660,7 +390,7 @@ static gboolean ensure_bus (NMModemManager *self) { /* Clear launch ID */ - self->priv->modem_manager_1_launch_id = 0; + self->priv->mm_launch_id = 0; if (!self->priv->dbus_connection) g_bus_get (G_BUS_TYPE_SYSTEM, @@ -675,20 +405,18 @@ ensure_bus (NMModemManager *self) } static void -schedule_modem_manager_1_relaunch (NMModemManager *self, - guint n_seconds) +schedule_modem_manager_relaunch (NMModemManager *self, + guint n_seconds) { /* No need to pass an extra reference to self; timeout/idle will be * cancelled if the object gets disposed. */ if (n_seconds) - self->priv->modem_manager_1_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_timeout_add_seconds (n_seconds, (GSourceFunc)ensure_bus, self); else - self->priv->modem_manager_1_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); + self->priv->mm_launch_id = g_idle_add ((GSourceFunc)ensure_bus, self); } -#endif /* WITH_MODEM_MANAGER_1 */ - /************************************************************************/ static void @@ -698,20 +426,7 @@ nm_modem_manager_init (NMModemManager *self) self->priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - /* ModemManager < 0.7 */ - self->priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (self->priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (nm_modem_manager_name_owner_changed), - self); - if (nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, MM_OLD_DBUS_SERVICE)) - modem_manager_appeared (self, TRUE); - else - modem_manager_disappeared (self); - -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - schedule_modem_manager_1_relaunch (self, 0); -#endif + schedule_modem_manager_relaunch (self, 0); } static void @@ -719,21 +434,20 @@ dispose (GObject *object) { NMModemManager *self = NM_MODEM_MANAGER (object); - /* ModemManager < 0.7 */ - clear_modem_manager_support (self); + if (self->priv->mm_launch_id) { + g_source_remove (self->priv->mm_launch_id); + self->priv->mm_launch_id = 0; + } -#if WITH_MODEM_MANAGER_1 - /* ModemManager >= 0.7 */ - clear_modem_manager_1_support (self); -#endif + modem_manager_clear_signals (self); + g_clear_object (&self->priv->modem_manager); + g_clear_object (&self->priv->dbus_connection); if (self->priv->modems) { g_hash_table_foreach_remove (self->priv->modems, remove_one_modem, object); g_hash_table_destroy (self->priv->modems); } - self->priv->dbus_mgr = NULL; - /* Chain up to the parent class */ G_OBJECT_CLASS (nm_modem_manager_parent_class)->dispose (object); } diff --git a/src/devices/wwan/nm-modem-manager.h b/src/devices/wwan/nm-modem-manager.h index 3082bdb3..9e0db41e 100644 --- a/src/devices/wwan/nm-modem-manager.h +++ b/src/devices/wwan/nm-modem-manager.h @@ -20,8 +20,8 @@ * Copyright (C) 2009 Canonical Ltd. */ -#ifndef NM_MODEM_MANAGER_H -#define NM_MODEM_MANAGER_H +#ifndef __NETWORKMANAGER_MODEM_MANAGER_H__ +#define __NETWORKMANAGER_MODEM_MANAGER_H__ #include #include "nm-modem.h" @@ -46,4 +46,4 @@ typedef struct { GType nm_modem_manager_get_type (void); -#endif /* NM_MODEM_MANAGER_H */ +#endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */ diff --git a/src/devices/wwan/nm-modem-old-types.h b/src/devices/wwan/nm-modem-old-types.h deleted file mode 100644 index 84065a68..00000000 --- a/src/devices/wwan/nm-modem-old-types.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_TYPES_H -#define NM_MODEM_OLD_TYPES_H - -#define MM_OLD_DBUS_SERVICE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_PATH "/org/freedesktop/ModemManager" -#define MM_OLD_DBUS_INTERFACE "org.freedesktop.ModemManager" -#define MM_OLD_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem" -#define MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE "org.freedesktop.ModemManager.Modem.Simple" -#define MM_OLD_DBUS_INTERFACE_MODEM_CDMA "org.freedesktop.ModemManager.Modem.Cdma" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD "org.freedesktop.ModemManager.Modem.Gsm.Card" -#define MM_OLD_DBUS_INTERFACE_MODEM_GSM_NETWORK "org.freedesktop.ModemManager.Modem.Gsm.Network" - -#define MM_OLD_MODEM_TYPE_UNKNOWN 0 -#define MM_OLD_MODEM_TYPE_GSM 1 -#define MM_OLD_MODEM_TYPE_CDMA 2 - -/* Errors */ - -#define MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER MM_OLD_DBUS_INTERFACE_MODEM ".NoCarrier" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE MM_OLD_DBUS_INTERFACE_MODEM ".NoDialtone" -#define MM_OLD_MODEM_CONNECT_ERROR_BUSY MM_OLD_DBUS_INTERFACE_MODEM ".Busy" -#define MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER MM_OLD_DBUS_INTERFACE_MODEM ".NoAnswer" - -#define MM_OLD_MODEM_ERROR "org.freedesktop.ModemManager.Modem.Gsm" - -#define MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED MM_OLD_MODEM_ERROR ".NetworkNotAllowed" -#define MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT MM_OLD_MODEM_ERROR ".NetworkTimeout" -#define MM_OLD_MODEM_ERROR_NO_NETWORK MM_OLD_MODEM_ERROR ".NoNetwork" -#define MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED MM_OLD_MODEM_ERROR ".SimNotInserted" -#define MM_OLD_MODEM_ERROR_SIM_PIN MM_OLD_MODEM_ERROR ".SimPinRequired" -#define MM_OLD_MODEM_ERROR_SIM_PUK MM_OLD_MODEM_ERROR ".SimPukRequired" -#define MM_OLD_MODEM_ERROR_SIM_WRONG MM_OLD_MODEM_ERROR ".SimWrong" -#define MM_OLD_MODEM_ERROR_WRONG_PASSWORD MM_OLD_MODEM_ERROR ".IncorrectPassword" - -typedef enum { - MM_OLD_MODEM_STATE_UNKNOWN = 0, - MM_OLD_MODEM_STATE_DISABLED = 10, - MM_OLD_MODEM_STATE_DISABLING = 20, - MM_OLD_MODEM_STATE_ENABLING = 30, - MM_OLD_MODEM_STATE_ENABLED = 40, - MM_OLD_MODEM_STATE_SEARCHING = 50, - MM_OLD_MODEM_STATE_REGISTERED = 60, - MM_OLD_MODEM_STATE_DISCONNECTING = 70, - MM_OLD_MODEM_STATE_CONNECTING = 80, - MM_OLD_MODEM_STATE_CONNECTED = 90, - - MM_OLD_MODEM_STATE_LAST = MM_OLD_MODEM_STATE_CONNECTED -} MMOldModemState; - -#endif /* NM_MODEM_OLD_TYPES_H */ diff --git a/src/devices/wwan/nm-modem-old.c b/src/devices/wwan/nm-modem-old.c deleted file mode 100644 index ce1a382e..00000000 --- a/src/devices/wwan/nm-modem-old.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#include -#include - -#include "nm-modem-old.h" -#include "nm-dbus-manager.h" -#include "nm-setting-connection.h" -#include "nm-properties-changed-signal.h" -#include "nm-modem-old-types.h" -#include "nm-logging.h" -#include "NetworkManagerUtils.h" -#include "nm-device-private.h" -#include "nm-dbus-glib-types.h" -#include "nm-glib-compat.h" - -G_DEFINE_TYPE (NMModemOld, nm_modem_old, NM_TYPE_MODEM) - -#define NM_MODEM_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM_OLD, NMModemOldPrivate)) - -typedef struct { - DBusGProxy *proxy; - DBusGProxy *props_proxy; - - MMOldModemState state; - NMDeviceModemCapabilities caps; - char *unlock_required; - - DBusGProxyCall *call; - GHashTable *connect_properties; - - guint32 pin_tries; - guint enable_delay_id; -} NMModemOldPrivate; - -#define CAPS_3GPP (NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS | NM_DEVICE_MODEM_CAPABILITY_LTE) - -/*****************************************************************************/ - -typedef enum { - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY = 0, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_GPRS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_EDGE, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_UMTS, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSDPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA, - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA, - - MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_LAST = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA -} MMModemDeprecatedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_MODE_ANY = 0, - MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED = 1, - MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED = 2, - MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY = 3, - MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY = 4, - MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED = 5, - MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY = 6, - - MM_MODEM_GSM_ALLOWED_MODE_LAST = MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY -} MMModemGsmAllowedMode; - -typedef enum { - MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN = 0x0000, - /* bits 0..4 order match Ericsson device bitmap */ - MM_MODEM_GSM_ALLOWED_AUTH_NONE = 0x0001, - MM_MODEM_GSM_ALLOWED_AUTH_PAP = 0x0002, - MM_MODEM_GSM_ALLOWED_AUTH_CHAP = 0x0004, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP = 0x0008, - MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2 = 0x0010, - MM_MODEM_GSM_ALLOWED_AUTH_EAP = 0x0020, - - MM_MODEM_GSM_ALLOWED_AUTH_LAST = MM_MODEM_GSM_ALLOWED_AUTH_EAP -} MMModemGsmAllowedAuth; - -static NMDeviceStateReason -translate_mm_error (GError *error) -{ - NMDeviceStateReason reason; - - if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_CARRIER)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_DIALTONE)) - reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_BUSY)) - reason = NM_DEVICE_STATE_REASON_MODEM_BUSY; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_CONNECT_ERROR_NO_ANSWER)) - reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_NOT_ALLOWED)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NETWORK_TIMEOUT)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_NO_NETWORK)) - reason = NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_NOT_INSERTED)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PUK)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) - reason = NM_DEVICE_STATE_REASON_GSM_SIM_WRONG; - else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_WRONG_PASSWORD)) - 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 dbus error detected: '%s'", dbus_g_error_get_name (error)); - reason = NM_DEVICE_STATE_REASON_UNKNOWN; - } - - /* FIXME: We have only GSM error messages here, and we have no idea which - activation state failed. Reasons like: - NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, - NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, - NM_DEVICE_STATE_REASON_GSM_APN_FAILED, - NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, - NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED - are not used. - */ - return reason; -} - -#define MAP_STATE(name) case MM_OLD_MODEM_STATE_##name: return NM_MODEM_STATE_##name; - -static NMModemState -mm_state_to_nm (MMOldModemState mm_state, const char *unlock_required) -{ - if (unlock_required && *unlock_required) - return NM_MODEM_STATE_LOCKED; - - switch (mm_state) { - MAP_STATE(UNKNOWN) - MAP_STATE(DISABLED) - MAP_STATE(DISABLING) - MAP_STATE(ENABLING) - MAP_STATE(ENABLED) - MAP_STATE(SEARCHING) - MAP_STATE(REGISTERED) - MAP_STATE(DISCONNECTING) - MAP_STATE(CONNECTING) - MAP_STATE(CONNECTED) - } - return NM_MODEM_STATE_UNKNOWN; -}; - -/*****************************************************************************/ - -static DBusGProxy * -nm_modem_old_get_proxy (NMModemOld *self, const char *interface) -{ - - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *current_iface; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), NULL); - - /* Default to the default interface. */ - if (interface == NULL) - interface = MM_OLD_DBUS_INTERFACE_MODEM; - - if (interface && !strcmp (interface, DBUS_INTERFACE_PROPERTIES)) - return priv->props_proxy; - - current_iface = dbus_g_proxy_get_interface (priv->proxy); - if (!current_iface || strcmp (current_iface, interface)) - dbus_g_proxy_set_interface (priv->proxy, interface); - - return priv->proxy; -} - -/*****************************************************************************/ -/* Query/Update enabled state */ - -static void -set_mm_enabled_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - nm_log_warn (LOGD_MB, "failed to enable/disable modem: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - nm_modem_set_prev_state (NM_MODEM (user_data), "enable/disable failed"); - } - /* Wait for the state change signal to indicate enabled state changed */ -} - -static void -set_mm_enabled (NMModem *self, gboolean enabled) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM), - "Enable", set_mm_enabled_done, - g_object_ref (self), g_object_unref, - G_TYPE_BOOLEAN, enabled, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -ask_for_pin (NMModemOld *self, gboolean always_ask) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - guint32 tries = 0; - - g_return_if_fail (NM_IS_MODEM_OLD (self)); - - if (!always_ask) - tries = priv->pin_tries++; - - nm_modem_get_secrets (NM_MODEM (self), - NM_SETTING_GSM_SETTING_NAME, - (tries || always_ask) ? TRUE : FALSE, - NM_SETTING_GSM_PIN); -} - -static void -stage1_prepare_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GError *error = NULL; - gboolean asked = FALSE; - - priv->call = NULL; - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, TRUE, NM_DEVICE_STATE_REASON_NONE); - else { - if (priv->caps & CAPS_3GPP) { - if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) { - ask_for_pin (self, FALSE); - asked = TRUE; - } else if (dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_WRONG)) { - ask_for_pin (self, TRUE); - asked = TRUE; - } - } - - if (!asked) { - nm_log_warn (LOGD_MB, "Mobile connection failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, translate_mm_error (error)); - } - g_error_free (error); - } -} - -static void -do_connect (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - DBusGProxy *proxy; - - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_SIMPLE); - priv->call = dbus_g_proxy_begin_call_with_timeout (proxy, - "Connect", stage1_prepare_done, - self, NULL, 120000, - DBUS_TYPE_G_MAP_OF_VARIANT, priv->connect_properties, - G_TYPE_INVALID); -} - -static void stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data); - -/* do_enable() is used as a GSourceFunc, hence the gboolean return */ -static gboolean -do_enable (NMModemOld *self) -{ - DBusGProxy *proxy; - - g_return_val_if_fail (NM_IS_MODEM_OLD (self), FALSE); - - NM_MODEM_OLD_GET_PRIVATE (self)->enable_delay_id = 0; - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM); - dbus_g_proxy_begin_call_with_timeout (proxy, - "Enable", stage1_enable_done, - self, NULL, 20000, - G_TYPE_BOOLEAN, TRUE, - G_TYPE_INVALID); - return FALSE; -} - -static void -stage1_pin_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { - /* Success; try to enable the modem again. Wait a few seconds to ensure - * that ModemManager is ready for the enable right after the unlock. - */ - if (priv->enable_delay_id == 0) - priv->enable_delay_id = g_timeout_add_seconds (4, (GSourceFunc) do_enable, self); - } else { - nm_log_warn (LOGD_MB, "GSM PIN unlock failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - g_error_free (error); - } -} - -static void -handle_enable_pin_required (NMModemOld *self) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - const char *pin = NULL; - GValue *value; - DBusGProxy *proxy; - - g_assert (priv->caps & CAPS_3GPP); - - /* See if we have a PIN already */ - value = g_hash_table_lookup (priv->connect_properties, "pin"); - if (value && G_VALUE_HOLDS_STRING (value)) - pin = g_value_get_string (value); - - /* If we do, send it */ - if (pin) { - proxy = nm_modem_old_get_proxy (NM_MODEM_OLD (self), MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD); - dbus_g_proxy_begin_call_with_timeout (proxy, - "SendPin", stage1_pin_done, - self, NULL, 10000, - G_TYPE_STRING, pin, - G_TYPE_INVALID); - } else - ask_for_pin (self, FALSE); -} - -static void -stage1_enable_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - NMDeviceStateReason reason; - GError *error = NULL; - - if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) - do_connect (self); - else { - if ((priv->caps & CAPS_3GPP) && dbus_g_error_has_name (error, MM_OLD_MODEM_ERROR_SIM_PIN)) - handle_enable_pin_required (self); - else { - nm_log_warn (LOGD_MB, "Modem enable failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - - /* try to translate the error reason */ - reason = translate_mm_error (error); - if (reason == NM_DEVICE_STATE_REASON_UNKNOWN) - reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED; - g_signal_emit_by_name (self, NM_MODEM_PREPARE_RESULT, FALSE, reason); - } - - g_error_free (error); - } -} - -static GHashTable * -create_connect_properties (NMConnection *connection) -{ - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - NMSettingPPP *s_ppp; - GHashTable *properties; - const char *str; - - properties = value_hash_create (); - - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - str = nm_setting_cdma_get_number (s_cdma); - if (str) - value_hash_add_str (properties, "number", str); - return properties; - } - - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - str = nm_setting_gsm_get_number (s_gsm); - if (str) - value_hash_add_str (properties, "number", str); - - str = nm_setting_gsm_get_apn (s_gsm); - if (str) - value_hash_add_str (properties, "apn", str); - - str = nm_setting_gsm_get_network_id (s_gsm); - if (str) - value_hash_add_str (properties, "network_id", str); - - str = nm_setting_gsm_get_pin (s_gsm); - if (str) - value_hash_add_str (properties, "pin", str); - - str = nm_setting_gsm_get_username (s_gsm); - if (str) - value_hash_add_str (properties, "username", str); - - str = nm_setting_gsm_get_password (s_gsm); - if (str) - value_hash_add_str (properties, "password", str); - -G_GNUC_BEGIN_IGNORE_DEPRECATIONS - /* Add both old and new preferred modes */ - switch (nm_setting_gsm_get_network_type (s_gsm)) { - case NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_PREFER_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_PREFERRED); - break; - case NM_SETTING_GSM_NETWORK_TYPE_4G: - /* deprecated modes not extended for 4G, so no need to set them here */ - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_4G_ONLY); - break; - default: - value_hash_add_uint (properties, "network_mode", MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY); - value_hash_add_uint (properties, "allowed_mode", MM_MODEM_GSM_ALLOWED_MODE_ANY); - break; - } -G_GNUC_END_IGNORE_DEPRECATIONS - - /* Roaming */ - if (nm_setting_gsm_get_home_only (s_gsm)) - value_hash_add_bool (properties, "home_only", TRUE); - - /* For IpMethod == STATIC or DHCP */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - guint32 auth = MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN; - - if (nm_setting_ppp_get_noauth (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_NONE; - if (!nm_setting_ppp_get_refuse_pap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_PAP; - if (!nm_setting_ppp_get_refuse_chap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_CHAP; - if (!nm_setting_ppp_get_refuse_mschap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAP; - if (!nm_setting_ppp_get_refuse_mschapv2 (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_MSCHAPV2; - if (!nm_setting_ppp_get_refuse_eap (s_ppp)) - auth |= MM_MODEM_GSM_ALLOWED_AUTH_EAP; - - if (auth != MM_MODEM_GSM_ALLOWED_AUTH_UNKNOWN) - value_hash_add_uint (properties, "allowed_auth", auth); - } - - return properties; - } - - g_hash_table_destroy (properties); - return NULL; -} - -static NMActStageReturn -act_stage1_prepare (NMModem *modem, - NMConnection *connection, - NMDeviceStateReason *reason) -{ - NMModemOld *self = NM_MODEM_OLD (modem); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - if (priv->connect_properties) - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = create_connect_properties (connection); - - if (nm_modem_get_state (modem) >= NM_MODEM_STATE_ENABLING) - do_connect (self); - else - do_enable (self); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ -/* IP method static */ - -static char addr_to_string_buf[INET6_ADDRSTRLEN + 1]; - -static const char * -ip_address_to_string (guint32 numeric) -{ - guint32 temp_addr; - - memset (&addr_to_string_buf, '\0', sizeof (addr_to_string_buf)); - temp_addr = numeric; - - if (inet_ntop (AF_INET, &temp_addr, addr_to_string_buf, INET_ADDRSTRLEN)) { - return addr_to_string_buf; - } else { - nm_log_warn (LOGD_VPN, "error converting IP4 address 0x%X", - ntohl (temp_addr)); - return NULL; - } -} - -static void -static_stage3_done (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValueArray *ret_array = NULL; - GError *error = NULL; - NMIP4Config *config = NULL; - - priv->call = NULL; - - /* Returned value array is (uuuu): [IP, DNS1, DNS2, DNS3], all in - * network byte order. - */ - if (dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_VALUE_ARRAY, &ret_array, - G_TYPE_INVALID)) { - NMPlatformIP4Address address; - int i; - - config = nm_ip4_config_new (); - memset (&address, 0, sizeof (address)); - - nm_log_info (LOGD_MB, "(%s): IPv4 static configuration:", - nm_modem_get_uid (NM_MODEM (self))); - - /* IP address */ - address.address = g_value_get_uint (g_value_array_get_nth (ret_array, 0)); - address.plen = 32; - address.source = NM_PLATFORM_SOURCE_WWAN; - nm_ip4_config_add_address (config, &address); - - nm_log_info (LOGD_MB, " address %s/%d", - ip_address_to_string (address.address), - address.plen); - - /* DNS servers */ - for (i = 1; i < ret_array->n_values; i++) { - GValue *value = g_value_array_get_nth (ret_array, i); - guint32 tmp = g_value_get_uint (value); - - if (tmp > 0) { - nm_ip4_config_add_nameserver (config, tmp); - nm_log_info (LOGD_MB, " DNS %s", ip_address_to_string (tmp)); - } - } - g_value_array_free (ret_array); - } - - g_signal_emit_by_name (self, NM_MODEM_IP4_CONFIG_RESULT, config, error); - g_clear_error (&error); -} - -static NMActStageReturn -static_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) -{ - NMModemOldPrivate *priv; - - g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - - priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->call = dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "GetIP4Config", static_stage3_done, - self, NULL, - G_TYPE_INVALID); - - return NM_ACT_STAGE_RETURN_POSTPONE; -} - -/*****************************************************************************/ - -static void -disconnect_done (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) -{ - GError *error = NULL; - gboolean warn = GPOINTER_TO_UINT (user_data); - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID) && warn) { - nm_log_info (LOGD_MB, "disconnect failed: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - } -} - -static void -disconnect (NMModem *self, - gboolean warn) -{ - dbus_g_proxy_begin_call (nm_modem_old_get_proxy (NM_MODEM_OLD (self), - MM_OLD_DBUS_INTERFACE_MODEM), - "Disconnect", - disconnect_done, - GUINT_TO_POINTER (warn), - NULL, - G_TYPE_INVALID); -} - -/*****************************************************************************/ - -static void -deactivate (NMModem *self, NMDevice *device) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - - priv->pin_tries = 0; - - if (priv->call) { - dbus_g_proxy_cancel_call (priv->proxy, priv->call); - priv->call = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - /* Chain up parent */ - NM_MODEM_CLASS (nm_modem_old_parent_class)->deactivate (self, device); -} - -/*****************************************************************************/ - -static void -modem_properties_changed (DBusGProxy *proxy, - const char *interface, - GHashTable *props, - gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (self); - GValue *value; - gboolean update_state = FALSE; - - if (strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM) && - strcmp (interface, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD)) - return; - - value = g_hash_table_lookup (props, "IpMethod"); - if (value && G_VALUE_HOLDS_UINT (value)) { - g_object_set (self, - NM_MODEM_IP_METHOD, g_value_get_uint (value), - NULL); - } - - value = g_hash_table_lookup (props, "SimIdentifier"); - if (value && G_VALUE_HOLDS_STRING (value)) { - const char *sim_id = g_value_get_string (value); - - g_object_set (self, - NM_MODEM_SIM_ID, (sim_id && *sim_id) ? sim_id : NULL, - NULL); - } - - value = g_hash_table_lookup (props, "UnlockRequired"); - if (value && G_VALUE_HOLDS_STRING (value)) { - g_free (priv->unlock_required); - priv->unlock_required = g_value_dup_string (value); - update_state = TRUE; - } - - value = g_hash_table_lookup (props, "State"); - if (value && G_VALUE_HOLDS_UINT (value)) { - priv->state = g_value_get_uint (value); - update_state = TRUE; - } - - if (update_state) { - nm_modem_set_state (NM_MODEM (self), - mm_state_to_nm (priv->state, priv->unlock_required), - NULL); - } -} - -/*****************************************************************************/ - -static gboolean -check_connection_compatible (NMModem *modem, NMConnection *connection) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingConnection *s_con; - gboolean valid_cdma = FALSE, valid_gsm = FALSE; - const char *ctype; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - ctype = nm_setting_connection_get_connection_type (s_con); - g_assert (ctype); - - /* Check for valid CDMA first */ - if (strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) == 0) - valid_cdma = !!nm_connection_get_setting_cdma (connection); - - if (strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) == 0) - valid_gsm = !!nm_connection_get_setting_gsm (connection); - - /* Validate CDMA */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - if (valid_cdma) - return TRUE; - - /* If the modem is only CDMA and the connection is not CDMA, error */ - if ((priv->caps ^ NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) == 0) - return FALSE; - } - - /* Validate 3GPP */ - if (priv->caps & CAPS_3GPP) - return valid_gsm; - - return FALSE; -} - -/*****************************************************************************/ - -static void -complete_ppp_setting (NMConnection *connection) -{ - NMSettingPPP *s_ppp; - - s_ppp = nm_connection_get_setting_ppp (connection); - if (!s_ppp) { - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); - g_object_set (G_OBJECT (s_ppp), - NM_SETTING_PPP_LCP_ECHO_FAILURE, 5, - NM_SETTING_PPP_LCP_ECHO_INTERVAL, 30, - NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ppp)); - } -} - -static gboolean -complete_connection_3gpp (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingGsm *s_gsm; - - s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { - /* Need an APN at least */ - g_set_error_literal (error, - NM_SETTING_GSM_ERROR, - NM_SETTING_GSM_ERROR_MISSING_PROPERTY, - NM_SETTING_GSM_APN); - return FALSE; - } - - if (!nm_setting_gsm_get_number (s_gsm)) - g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_GSM_SETTING_NAME, - existing_connections, - _("GSM connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection_cdma (NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMSettingCdma *s_cdma; - - s_cdma = nm_connection_get_setting_cdma (connection); - if (!s_cdma) { - s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); - nm_connection_add_setting (connection, NM_SETTING (s_cdma)); - } - - if (!nm_setting_cdma_get_number (s_cdma)) - g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); - - complete_ppp_setting (connection); - - nm_utils_complete_generic (connection, - NM_SETTING_CDMA_SETTING_NAME, - existing_connections, - _("CDMA connection %d"), - NULL, - FALSE); /* No IPv6 yet by default */ - return TRUE; -} - -static gboolean -complete_connection (NMModem *modem, - NMConnection *connection, - const GSList *existing_connections, - GError **error) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - - /* If the modem has LTE, complete as 3GPP */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_LTE) - return complete_connection_3gpp (connection, existing_connections, error); - - /* Otherwise, prefer CDMA on the theory that if the modem has CDMA/EVDO - * that's most likely what the user will be using. - */ - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) - return complete_connection_cdma (connection, existing_connections, error); - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) - return complete_connection_3gpp (connection, existing_connections, error); - - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, - "Modem had no WWAN capabilities."); - return FALSE; -} - -/*****************************************************************************/ - -static gboolean -get_user_pass (NMModem *modem, - NMConnection *connection, - const char **user, - const char **pass) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (modem); - NMSettingCdma *s_cdma; - NMSettingGsm *s_gsm; - - if (priv->caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { - s_cdma = nm_connection_get_setting_cdma (connection); - if (s_cdma) { - if (user) - *user = nm_setting_cdma_get_username (s_cdma); - if (pass) - *pass = nm_setting_cdma_get_password (s_cdma); - return TRUE; - } - } - - /* Fall back to GSM; will be used for CDMA devices on LTE networks too */ - s_gsm = nm_connection_get_setting_gsm (connection); - if (s_gsm) { - if (user) - *user = nm_setting_gsm_get_username (s_gsm); - if (pass) - *pass = nm_setting_gsm_get_password (s_gsm); - return TRUE; - } - - return FALSE; -} - -/*****************************************************************************/ - -static void -get_capabilities (NMModem *_self, - NMDeviceModemCapabilities *modem_caps, - NMDeviceModemCapabilities *current_caps) -{ - NMModemOld *self = NM_MODEM_OLD (_self); - - *current_caps = *modem_caps = NM_MODEM_OLD_GET_PRIVATE (self)->caps; -} - -/*****************************************************************************/ - -NMModem * -nm_modem_old_new (const char *path, GHashTable *properties, GError **error) -{ - NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE; - NMModemOld *self; - GHashTableIter iter; - const char *prop; - GValue *value; - const char *data_device = NULL; - const char *driver = NULL; - const char *master_device = NULL; - const char *unlock_required = NULL; - const char *device_id = NULL; - guint32 modem_type = MM_OLD_MODEM_TYPE_UNKNOWN; - guint32 ip_method = MM_MODEM_IP_METHOD_PPP; - guint32 ip_timeout = 0; - MMOldModemState state = MM_OLD_MODEM_STATE_UNKNOWN; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (properties != NULL, NULL); - - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, (gpointer) &prop, (gpointer) &value)) { - if (g_strcmp0 (prop, "Type") == 0) - modem_type = g_value_get_uint (value); - else if (g_strcmp0 (prop, "MasterDevice") == 0) - master_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpMethod") == 0) - ip_method = g_value_get_uint (value); - else if (g_strcmp0 (prop, "Device") == 0) - data_device = g_value_get_string (value); - else if (g_strcmp0 (prop, "Driver") == 0) - driver = g_value_get_string (value); - else if (g_strcmp0 (prop, "IpTimeout") == 0) - ip_timeout = g_value_get_uint (value); - else if (g_strcmp0 (prop, "State") == 0) - state = g_value_get_uint (value); - else if (g_strcmp0 (prop, "UnlockRequired") == 0) - unlock_required = g_value_get_string (value); - else if (g_strcmp0 (prop, "DeviceIdentifier") == 0) - device_id = g_value_get_string (value); - } - - if (modem_type == MM_OLD_MODEM_TYPE_UNKNOWN) { - g_set_error (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Unhandled modem type %d", modem_type); - return NULL; - } - - if (!master_device || !strlen (master_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem master device."); - return NULL; - } - - if (!driver || !strlen (driver)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem driver."); - return NULL; - } - - if (!data_device || !strlen (data_device)) { - g_set_error_literal (error, NM_MODEM_ERROR, NM_MODEM_ERROR_INITIALIZATION_FAILED, - "Failed to retrieve modem data device."); - return NULL; - } - - self = (NMModemOld *) g_object_new (NM_TYPE_MODEM_OLD, - NM_MODEM_PATH, path, - NM_MODEM_DRIVER, driver, - NM_MODEM_UID, data_device, - NM_MODEM_CONTROL_PORT, NULL, - NM_MODEM_DATA_PORT, data_device, - NM_MODEM_IP_METHOD, ip_method, - NM_MODEM_IP_TIMEOUT, ip_timeout, - NM_MODEM_DEVICE_ID, device_id, - NM_MODEM_STATE, mm_state_to_nm (state, unlock_required), - NULL); - if (self) { - if (modem_type == MM_OLD_MODEM_TYPE_CDMA) - caps |= NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO; - if (modem_type == MM_OLD_MODEM_TYPE_GSM) - caps |= NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS; - - NM_MODEM_OLD_GET_PRIVATE (self)->caps = caps; - NM_MODEM_OLD_GET_PRIVATE (self)->state = state; - NM_MODEM_OLD_GET_PRIVATE (self)->unlock_required = g_strdup (unlock_required); - } - - return (NMModem *) self; -} - -static void -nm_modem_old_init (NMModemOld *self) -{ -} - -static void -get_sim_id_done (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMModemOld *self = NM_MODEM_OLD (user_data); - GValue value = G_VALUE_INIT; - - if (dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - if (G_VALUE_HOLDS_STRING (&value)) { - const char *sim_id = g_value_get_string (&value); - - if (sim_id && *sim_id) - g_object_set (G_OBJECT (self), NM_MODEM_SIM_ID, sim_id, NULL); - } - g_value_unset (&value); - } -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMModemOldPrivate *priv; - DBusGConnection *bus; - - object = G_OBJECT_CLASS (nm_modem_old_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - priv = NM_MODEM_OLD_GET_PRIVATE (object); - - bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - priv->proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - MM_OLD_DBUS_INTERFACE_MODEM); - - priv->props_proxy = dbus_g_proxy_new_for_name (bus, - MM_OLD_DBUS_SERVICE, - nm_modem_get_path (NM_MODEM (object)), - DBUS_INTERFACE_PROPERTIES); - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - G_TYPE_NONE, - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->props_proxy, "MmPropertiesChanged", - G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->props_proxy, "MmPropertiesChanged", - G_CALLBACK (modem_properties_changed), - object, - NULL); - - /* Request the SIM ID */ - dbus_g_proxy_begin_call (priv->props_proxy, - "Get", - get_sim_id_done, - g_object_ref (object), g_object_unref, - G_TYPE_STRING, MM_OLD_DBUS_INTERFACE_MODEM_GSM_CARD, - G_TYPE_STRING, "SimIdentifier", - G_TYPE_INVALID); - - return object; -} - -static void -dispose (GObject *object) -{ - NMModemOldPrivate *priv = NM_MODEM_OLD_GET_PRIVATE (object); - - if (priv->proxy) { - g_object_unref (priv->proxy); - priv->proxy = NULL; - } - - if (priv->props_proxy) { - g_object_unref (priv->props_proxy); - priv->props_proxy = NULL; - } - - if (priv->connect_properties) { - g_hash_table_destroy (priv->connect_properties); - priv->connect_properties = NULL; - } - - if (priv->enable_delay_id) { - g_source_remove (priv->enable_delay_id); - priv->enable_delay_id = 0; - } - - g_free (priv->unlock_required); - priv->unlock_required = NULL; - - G_OBJECT_CLASS (nm_modem_old_parent_class)->dispose (object); -} - -static void -nm_modem_old_class_init (NMModemOldClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMModemClass *modem_class = NM_MODEM_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMModemOldPrivate)); - - /* Virtual methods */ - object_class->constructor = constructor; - object_class->dispose = dispose; - - modem_class->get_capabilities = get_capabilities; - modem_class->get_user_pass = get_user_pass; - modem_class->complete_connection = complete_connection; - modem_class->check_connection_compatible = check_connection_compatible; - modem_class->act_stage1_prepare = act_stage1_prepare; - modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; - modem_class->disconnect = disconnect; - modem_class->deactivate = deactivate; - modem_class->set_mm_enabled = set_mm_enabled; -} diff --git a/src/devices/wwan/nm-modem-old.h b/src/devices/wwan/nm-modem-old.h deleted file mode 100644 index 65e3db2d..00000000 --- a/src/devices/wwan/nm-modem-old.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 - 2011 Red Hat, Inc. - * Copyright (C) 2009 Novell, Inc. - */ - -#ifndef NM_MODEM_OLD_H -#define NM_MODEM_OLD_H - -#include -#include -#include "nm-modem.h" -#include "nm-modem-old-types.h" - -G_BEGIN_DECLS - -#define NM_TYPE_MODEM_OLD (nm_modem_old_get_type ()) -#define NM_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MODEM_OLD, NMModemOld)) -#define NM_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MODEM_OLD, NMModemOldClass)) -#define NM_IS_MODEM_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MODEM_OLD)) -#define NM_IS_MODEM_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MODEM_OLD)) -#define NM_MODEM_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MODEM_OLD, NMModemOldClass)) - -typedef struct { - NMModem parent; -} NMModemOld; - -typedef struct { - NMModemClass parent; -} NMModemOldClass; - -GType nm_modem_old_get_type (void); - -NMModem *nm_modem_old_new (const char *path, GHashTable *properties, GError **error); - -G_END_DECLS - -#endif /* NM_MODEM_OLD_H */ diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index fd3b4a36..ba1db8a4 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -19,6 +19,8 @@ * Copyright (C) 2009 Novell, Inc. */ +#include "config.h" + #include #include "nm-modem.h" #include "nm-platform.h" @@ -42,11 +44,13 @@ enum { PROP_PATH, PROP_UID, PROP_DRIVER, - PROP_IP_METHOD, + PROP_IP4_METHOD, + PROP_IP6_METHOD, PROP_IP_TIMEOUT, PROP_STATE, PROP_DEVICE_ID, PROP_SIM_ID, + PROP_IP_TYPES, LAST_PROP }; @@ -58,11 +62,14 @@ typedef struct { char *control_port; char *data_port; char *ppp_iface; - guint32 ip_method; + NMModemIPMethod ip4_method; + NMModemIPMethod ip6_method; + NMUtilsIPv6IfaceId iid; NMModemState state; NMModemState prev_state; /* revert to this state if enable/disable fails */ char *device_id; char *sim_id; + NMModemIPType ip_types; NMPPPManager *ppp_manager; @@ -82,6 +89,7 @@ enum { PPP_FAILED, PREPARE_RESULT, IP4_CONFIG_RESULT, + IP6_CONFIG_RESULT, AUTH_REQUESTED, AUTH_RESULT, REMOVED, @@ -93,17 +101,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -/*****************************************************************************/ - -GQuark -nm_modem_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-modem-error"); - return quark; -} - /*****************************************************************************/ /* State/enabled/connected */ @@ -126,7 +123,7 @@ static const char *state_table[] = { const char * nm_modem_state_to_string (NMModemState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return NULL; } @@ -218,6 +215,102 @@ nm_modem_emit_removed (NMModem *self) g_signal_emit (self, signals[REMOVED], 0); } +NMModemIPType +nm_modem_get_supported_ip_types (NMModem *self) +{ + return NM_MODEM_GET_PRIVATE (self)->ip_types; +} + +/** + * nm_modem_get_connection_ip_type: + * @self: the #NMModem + * @connection: the #NMConnection to determine IP type to use + * + * Given a modem and a connection, determine which NMModemIpType to use + * when connecting. + * + * Returns: a single %NMModemIpType value + */ +NMModemIPType +nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMSettingIPConfig *s_ip4, *s_ip6; + const char *method; + gboolean ip4 = TRUE, ip6 = TRUE; + gboolean ip4_may_fail = TRUE, ip6_may_fail = TRUE; + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + if (s_ip4) { + method = nm_setting_ip_config_get_method (s_ip4); + if (g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + ip4 = FALSE; + ip4_may_fail = nm_setting_ip_config_get_may_fail (s_ip4); + } + + s_ip6 = nm_connection_get_setting_ip6_config (connection); + if (s_ip6) { + method = nm_setting_ip_config_get_method (s_ip6); + if (g_strcmp0 (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + ip6 = FALSE; + ip6_may_fail = nm_setting_ip_config_get_may_fail (s_ip6); + } + + if (ip4 && !ip6) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV4)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv4 but IPv4 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV4; + } + + if (ip6 && !ip4) { + if (!(priv->ip_types & NM_MODEM_IP_TYPE_IPV6)) { + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested IPv6 but IPv6 is " + "unsuported by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + return NM_MODEM_IP_TYPE_IPV6; + } + + if (ip4 && ip6) { + /* Modem supports dual-stack */ + if (priv->ip_types & NM_MODEM_IP_TYPE_IPV4V6) + return NM_MODEM_IP_TYPE_IPV4V6; + + /* Both IPv4 and IPv6 requested, but modem doesn't support dual-stack; + * if one method is marked "may-fail" then use the other. + */ + if (ip6_may_fail) + return NM_MODEM_IP_TYPE_IPV4; + else if (ip4_may_fail) + return NM_MODEM_IP_TYPE_IPV6; + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection requested both IPv4 and IPv6 " + "but dual-stack addressing is unsupported " + "by the modem."); + return NM_MODEM_IP_TYPE_UNKNOWN; + } + + g_set_error_literal (error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + "Connection specified no IP configuration!"); + return NM_MODEM_IP_TYPE_UNKNOWN; +} + /*****************************************************************************/ /* IP method PPP */ @@ -236,6 +329,18 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ } } +static void +set_data_port (NMModem *self, const char *new_data_port) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + + if (g_strcmp0 (priv->data_port, new_data_port) != 0) { + g_free (priv->data_port); + priv->data_port = g_strdup (new_data_port); + g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + } +} + static void ppp_ip4_config (NMPPPManager *ppp_manager, const char *iface, @@ -243,7 +348,6 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gpointer user_data) { NMModem *self = NM_MODEM (user_data); - NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); guint32 i, num; guint32 bad_dns1 = htonl (0x0A0B0C0D); guint32 good_dns1 = htonl (0x04020201); /* GTE nameserver */ @@ -252,9 +356,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager, gboolean dns_workaround = FALSE; /* Notify about the new data port to use */ - g_free (priv->ppp_iface); - priv->ppp_iface = g_strdup (iface); - g_object_notify (G_OBJECT (self), NM_MODEM_DATA_PORT); + set_data_port (self, iface); /* Work around a PPP bug (#1732) which causes many mobile broadband * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. @@ -295,6 +397,23 @@ ppp_ip4_config (NMPPPManager *ppp_manager, g_signal_emit (self, signals[IP4_CONFIG_RESULT], 0, config, NULL); } +static void +ppp_ip6_config (NMPPPManager *ppp_manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config, + gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + + /* Notify about the new data port to use */ + set_data_port (self, iface); + + NM_MODEM_GET_PRIVATE (self)->iid = *iid; + + nm_modem_emit_ip6_config_result (self, config, NULL); +} + static void ppp_stats (NMPPPManager *ppp_manager, guint32 in_bytes, @@ -313,20 +432,27 @@ ppp_stats (NMPPPManager *ppp_manager, } static NMActStageReturn -ppp_stage3_ip4_config_start (NMModem *self, - NMActRequest *req, - NMDeviceStateReason *reason) +ppp_stage3_ip_config_start (NMModem *self, + NMActRequest *req, + NMDeviceStateReason *reason) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); const char *ppp_name = NULL; GError *error = NULL; NMActStageReturn ret; - guint ip_timeout = 20; + guint ip_timeout = 30; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + /* If we're already running PPP don't restart it; for example, if both + * IPv4 and IPv6 are requested, IPv4 gets started first, but we use the + * same pppd for both v4 and v6. + */ + if (priv->ppp_manager) + return NM_ACT_STAGE_RETURN_POSTPONE; + if (NM_MODEM_GET_CLASS (self)->get_user_pass) { NMConnection *connection = nm_act_request_get_connection (req); @@ -336,7 +462,7 @@ ppp_stage3_ip4_config_start (NMModem *self, } /* Check if ModemManager requested a specific IP timeout to be used. If 0 reported, - * use the default one (20s) */ + * use the default one (30s) */ if (priv->mm_ip_timeout > 0) { nm_log_info (LOGD_PPP, "using modem-specified IP timeout: %u seconds", priv->mm_ip_timeout); @@ -351,6 +477,9 @@ ppp_stage3_ip4_config_start (NMModem *self, g_signal_connect (priv->ppp_manager, "ip4-config", G_CALLBACK (ppp_ip4_config), self); + g_signal_connect (priv->ppp_manager, "ip6-config", + G_CALLBACK (ppp_ip6_config), + self); g_signal_connect (priv->ppp_manager, "stats", G_CALLBACK (ppp_stats), self); @@ -382,6 +511,8 @@ nm_modem_stage3_ip4_config_start (NMModem *self, { NMModemPrivate *priv; NMActRequest *req; + NMConnection *connection; + const char *method; NMActStageReturn ret; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -391,21 +522,36 @@ nm_modem_stage3_ip4_config_start (NMModem *self, req = nm_device_get_act_request (device); g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + + /* Only Disabled and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP4, + "(%s): unhandled WWAN IPv4 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } priv = NM_MODEM_GET_PRIVATE (self); - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - ret = ppp_stage3_ip4_config_start (self, req, reason); + switch (priv->ip4_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_STATIC: ret = NM_MODEM_GET_CLASS (self)->static_stage3_ip4_config_start (self, req, reason); break; - case MM_MODEM_IP_METHOD_DHCP: + case NM_MODEM_IP_METHOD_AUTO: ret = device_class->act_stage3_ip4_config_start (device, NULL, reason); break; default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - ret = NM_ACT_STAGE_RETURN_FAILURE; + nm_log_info (LOGD_MB, "(%s): IPv4 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; break; } @@ -423,8 +569,8 @@ nm_modem_ip4_pre_commit (NMModem *modem, * not point-to-point) and IP config has a /32 prefix, then we assume that * ARP will be pointless and we turn it off. */ - if ( priv->ip_method == MM_MODEM_IP_METHOD_STATIC - || priv->ip_method == MM_MODEM_IP_METHOD_DHCP) { + if ( priv->ip4_method == NM_MODEM_IP_METHOD_STATIC + || priv->ip4_method == NM_MODEM_IP_METHOD_AUTO) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, 0); g_assert (address); @@ -435,15 +581,100 @@ nm_modem_ip4_pre_commit (NMModem *modem, /*****************************************************************************/ +void +nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + guint i, num; + gboolean do_slaac = TRUE; + + if (error) { + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, NULL, FALSE, error); + return; + } + + if (config) { + /* If the IPv6 configuration only included a Link-Local address, then + * we have to run SLAAC to get the full IPv6 configuration. + */ + num = nm_ip6_config_get_num_addresses (config); + g_assert (num > 0); + for (i = 0; i < num; i++) { + const NMPlatformIP6Address * addr = nm_ip6_config_get_address (config, i); + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) { + if (!priv->iid.id) + priv->iid.id = ((guint64 *)(&addr->address.s6_addr))[1]; + } else + do_slaac = FALSE; + } + } + g_assert (config || do_slaac); + + g_signal_emit (self, signals[IP6_CONFIG_RESULT], 0, config, do_slaac, NULL); +} + +static NMActStageReturn +stage3_ip6_config_request (NMModem *self, NMDeviceStateReason *reason) +{ + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; +} + NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *self, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason) { - /* FIXME: We don't support IPv6 on modems quite yet... */ - nm_device_activate_schedule_ip6_config_timeout (device); - return NM_ACT_STAGE_RETURN_POSTPONE; + NMModemPrivate *priv; + NMActStageReturn ret; + NMConnection *connection; + const char *method; + + g_return_val_if_fail (self != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_connection (req); + g_assert (connection); + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + + /* Only Ignore and Auto methods make sense for WWAN */ + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) + return NM_ACT_STAGE_RETURN_STOP; + + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) != 0) { + nm_log_warn (LOGD_MB | LOGD_IP6, + "(%s): unhandled WWAN IPv6 method '%s'; will fail", + nm_modem_get_uid (self), method); + *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv = NM_MODEM_GET_PRIVATE (self); + switch (priv->ip6_method) { + case NM_MODEM_IP_METHOD_PPP: + ret = ppp_stage3_ip_config_start (self, req, reason); + break; + case NM_MODEM_IP_METHOD_STATIC: + case NM_MODEM_IP_METHOD_AUTO: + /* Both static and DHCP/Auto retrieve a base IP config from the modem + * which in the static case is the full config, and the DHCP/Auto case + * is just the IPv6LL address to use for SLAAC. + */ + ret = NM_MODEM_GET_CLASS (self)->stage3_ip6_config_request (self, reason); + break; + default: + nm_log_info (LOGD_MB, "(%s): IPv6 configuration disabled", nm_modem_get_uid (self)); + ret = NM_ACT_STAGE_RETURN_STOP; + break; + } + + return ret; } /*****************************************************************************/ @@ -486,12 +717,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -524,7 +755,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; NMConnection *connection; if (priv->act_request) @@ -543,7 +774,7 @@ nm_modem_act_stage1_prepare (NMModem *self, /* Secrets required... */ if (priv->secrets_tries++) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, @@ -633,22 +864,19 @@ deactivate (NMModem *self, NMDevice *device) priv->ppp_manager = NULL; } - switch (priv->ip_method) { - case MM_MODEM_IP_METHOD_PPP: - break; - case MM_MODEM_IP_METHOD_STATIC: - case MM_MODEM_IP_METHOD_DHCP: + if (priv->ip4_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip4_method == NM_MODEM_IP_METHOD_AUTO || + priv->ip6_method == NM_MODEM_IP_METHOD_STATIC || + priv->ip6_method == NM_MODEM_IP_METHOD_AUTO) { ifindex = nm_device_get_ip_ifindex (device); if (ifindex > 0) { nm_platform_route_flush (ifindex); nm_platform_address_flush (ifindex); nm_platform_link_set_down (ifindex); } - break; - default: - nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); - break; } + priv->ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + priv->ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; g_free (priv->ppp_iface); priv->ppp_iface = NULL; @@ -772,6 +1000,15 @@ nm_modem_owns_port (NMModem *self, const char *iface) return FALSE; } +gboolean +nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid) +{ + g_return_val_if_fail (NM_IS_MODEM (self), FALSE); + + *out_iid = NM_MODEM_GET_PRIVATE (self)->iid; + return TRUE; +} + /*****************************************************************************/ void @@ -846,8 +1083,11 @@ get_property (GObject *object, guint prop_id, case PROP_UID: g_value_set_string (value, priv->uid); break; - case PROP_IP_METHOD: - g_value_set_uint (value, priv->ip_method); + case PROP_IP4_METHOD: + g_value_set_uint (value, priv->ip4_method); + break; + case PROP_IP6_METHOD: + g_value_set_uint (value, priv->ip6_method); break; case PROP_IP_TIMEOUT: g_value_set_uint (value, priv->mm_ip_timeout); @@ -861,6 +1101,9 @@ get_property (GObject *object, guint prop_id, case PROP_SIM_ID: g_value_set_string (value, priv->sim_id); break; + case PROP_IP_TYPES: + g_value_set_uint (value, priv->ip_types); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -892,8 +1135,11 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->uid = g_value_dup_string (value); break; - case PROP_IP_METHOD: - priv->ip_method = g_value_get_uint (value); + case PROP_IP4_METHOD: + priv->ip4_method = g_value_get_uint (value); + break; + case PROP_IP6_METHOD: + priv->ip6_method = g_value_get_uint (value); break; case PROP_IP_TIMEOUT: priv->mm_ip_timeout = g_value_get_uint (value); @@ -909,6 +1155,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->sim_id); priv->sim_id = g_value_dup_string (value); break; + case PROP_IP_TYPES: + priv->ip_types = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -959,92 +1208,100 @@ nm_modem_class_init (NMModemClass *klass) object_class->finalize = finalize; klass->act_stage1_prepare = act_stage1_prepare; + klass->stage3_ip6_config_request = stage3_ip6_config_request; klass->deactivate = deactivate; /* Properties */ g_object_class_install_property (object_class, PROP_UID, - g_param_spec_string (NM_MODEM_UID, - "UID", - "Modem unique ID", + g_param_spec_string (NM_MODEM_UID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_MODEM_PATH, - "DBus path", - "DBus path", + g_param_spec_string (NM_MODEM_PATH, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DRIVER, - g_param_spec_string (NM_MODEM_DRIVER, - "Driver", - "Driver", + g_param_spec_string (NM_MODEM_DRIVER, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONTROL_PORT, - g_param_spec_string (NM_MODEM_CONTROL_PORT, - "Control port", - "The port controlling the modem", + g_param_spec_string (NM_MODEM_CONTROL_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DATA_PORT, - g_param_spec_string (NM_MODEM_DATA_PORT, - "Data port", - "The port to connect to", + g_param_spec_string (NM_MODEM_DATA_PORT, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property - (object_class, PROP_IP_METHOD, - g_param_spec_uint (NM_MODEM_IP_METHOD, - "IP method", - "IP method", - MM_MODEM_IP_METHOD_PPP, - MM_MODEM_IP_METHOD_DHCP, - MM_MODEM_IP_METHOD_PPP, - G_PARAM_READWRITE)); + (object_class, PROP_IP4_METHOD, + g_param_spec_uint (NM_MODEM_IP4_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP6_METHOD, + g_param_spec_uint (NM_MODEM_IP6_METHOD, "", "", + NM_MODEM_IP_METHOD_UNKNOWN, + NM_MODEM_IP_METHOD_AUTO, + NM_MODEM_IP_METHOD_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IP_TIMEOUT, - g_param_spec_uint (NM_MODEM_IP_TIMEOUT, - "IP timeout", - "IP timeout", + g_param_spec_uint (NM_MODEM_IP_TIMEOUT, "", "", 0, 360, 20, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_enum (NM_MODEM_STATE, - "State", - "State", - NM_TYPE_MODEM_STATE, - NM_MODEM_STATE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_enum (NM_MODEM_STATE, "", "", + NM_TYPE_MODEM_STATE, + NM_MODEM_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICE_ID, - g_param_spec_string (NM_MODEM_DEVICE_ID, - "DeviceId", - "Device ID", + g_param_spec_string (NM_MODEM_DEVICE_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_SIM_ID, - g_param_spec_string (NM_MODEM_SIM_ID, - "SimId", - "Sim ID", + g_param_spec_string (NM_MODEM_SIM_ID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP_TYPES, + g_param_spec_uint (NM_MODEM_IP_TYPES, + "IP Types", + "Supported IP types", + 0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /* Signals */ @@ -1073,6 +1330,27 @@ nm_modem_class_init (NMModemClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_POINTER); + /** + * NMModem::ip6-config-result: + * @modem: the #NMModem on which the signal is emitted + * @config: the #NMIP6Config to apply to the modem's data port + * @do_slaac: %TRUE if IPv6 SLAAC should be started + * @error: a #GError if any error occurred during IP configuration + * + * This signal is emitted when IPv6 configuration has completed or failed. + * If @error is set the configuration failed. If @config is set, then + * the details should be applied to the data port before any further + * configuration (like SLAAC) is done. @do_slaac indicates whether SLAAC + * should be started after applying @config to the data port. + */ + signals[IP6_CONFIG_RESULT] = + g_signal_new (NM_MODEM_IP6_CONFIG_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, ip6_config_result), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_POINTER); + signals[PREPARE_RESULT] = g_signal_new (NM_MODEM_PREPARE_RESULT, G_OBJECT_CLASS_TYPE (object_class), @@ -1112,8 +1390,4 @@ nm_modem_class_init (NMModemClass *klass) G_STRUCT_OFFSET (NMModemClass, state_changed), NULL, NULL, NULL, G_TYPE_NONE, 2, NM_TYPE_MODEM_STATE, NM_TYPE_MODEM_STATE); - - dbus_g_error_domain_register (NM_MODEM_ERROR, - NM_DBUS_INTERFACE_DEVICE_MODEM, - NM_TYPE_MODEM_ERROR); } diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c992cf72..2a4d9173 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -19,10 +19,9 @@ * Copyright (C) 2009 Novell, Inc. */ -#ifndef NM_MODEM_H -#define NM_MODEM_H +#ifndef __NETWORKMANAGER_MODEM_H__ +#define __NETWORKMANAGER_MODEM_H__ -#include #include #include "ppp-manager/nm-ppp-manager.h" #include "nm-device.h" @@ -42,33 +41,50 @@ G_BEGIN_DECLS #define NM_MODEM_DRIVER "driver" #define NM_MODEM_CONTROL_PORT "control-port" #define NM_MODEM_DATA_PORT "data-port" -#define NM_MODEM_IP_METHOD "ip-method" +#define NM_MODEM_IP4_METHOD "ip4-method" +#define NM_MODEM_IP6_METHOD "ip6-method" #define NM_MODEM_IP_TIMEOUT "ip-timeout" #define NM_MODEM_STATE "state" #define NM_MODEM_DEVICE_ID "device-id" #define NM_MODEM_SIM_ID "sim-id" +#define NM_MODEM_IP_TYPES "ip-types" /* Supported IP types */ /* Signals */ #define NM_MODEM_PPP_STATS "ppp-stats" #define NM_MODEM_PPP_FAILED "ppp-failed" #define NM_MODEM_PREPARE_RESULT "prepare-result" #define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result" +#define NM_MODEM_IP6_CONFIG_RESULT "ip6-config-result" #define NM_MODEM_AUTH_REQUESTED "auth-requested" #define NM_MODEM_AUTH_RESULT "auth-result" #define NM_MODEM_REMOVED "removed" #define NM_MODEM_STATE_CHANGED "state-changed" -#define MM_MODEM_IP_METHOD_PPP 0 -#define MM_MODEM_IP_METHOD_STATIC 1 -#define MM_MODEM_IP_METHOD_DHCP 2 - typedef enum { - NM_MODEM_ERROR_CONNECTION_NOT_GSM, /*< nick=ConnectionNotGsm >*/ - NM_MODEM_ERROR_CONNECTION_NOT_CDMA, /*< nick=ConnectionNotCdma >*/ - NM_MODEM_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_MODEM_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ - NM_MODEM_ERROR_INITIALIZATION_FAILED, /*< nick=InitializationFailed >*/ -} NMModemError; + NM_MODEM_IP_METHOD_UNKNOWN = 0, + NM_MODEM_IP_METHOD_PPP, + NM_MODEM_IP_METHOD_STATIC, + NM_MODEM_IP_METHOD_AUTO, /* DHCP and/or SLAAC */ +} NMModemIPMethod; + +/** + * NMModemIPType: + * @NM_MODEM_IP_TYPE_UNKNOWN: unknown or no IP support + * @NM_MODEM_IP_TYPE_IPV4: IPv4-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV6: IPv6-only bearers are supported + * @NM_MODEM_IP_TYPE_IPV4V6: dual-stack IPv4 + IPv6 bearers are supported + * + * Indicates what IP protocols the modem supports for an IP bearer. Any + * combination of flags is possible. For example, (%NM_MODEM_IP_TYPE_IPV4 | + * %NM_MODEM_IP_TYPE_IPV6) indicates that the modem supports IPv4 and IPv6 + * but not simultaneously on the same bearer. + */ +typedef enum { + NM_MODEM_IP_TYPE_UNKNOWN = 0x0, + NM_MODEM_IP_TYPE_IPV4 = 0x1, + NM_MODEM_IP_TYPE_IPV6 = 0x2, + NM_MODEM_IP_TYPE_IPV4V6 = 0x4 +} NMModemIPType; typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_UNKNOWN = 0, @@ -86,9 +102,6 @@ typedef enum { /*< underscore_name=nm_modem_state >*/ NM_MODEM_STATE_CONNECTED = 12, } NMModemState; -#define NM_MODEM_ERROR (nm_modem_error_quark ()) -GQuark nm_modem_error_quark (void); - typedef struct { GObject parent; @@ -122,6 +135,12 @@ typedef struct { NMActRequest *req, NMDeviceStateReason *reason); + /* Request the IP6 config; when the config returns the modem + * subclass should emit the ip6_config_result signal. + */ + NMActStageReturn (*stage3_ip6_config_request) (NMModem *self, + NMDeviceStateReason *reason); + void (*set_mm_enabled) (NMModem *self, gboolean enabled); void (*disconnect) (NMModem *self, gboolean warn); @@ -136,6 +155,10 @@ typedef struct { void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason); void (*ip4_config_result) (NMModem *self, NMIP4Config *config, GError *error); + void (*ip6_config_result) (NMModem *self, + NMIP6Config *config, + gboolean do_slaac, + GError *error); void (*auth_requested) (NMModem *self); void (*auth_result) (NMModem *self, GError *error); @@ -154,6 +177,7 @@ const char *nm_modem_get_uid (NMModem *modem); const char *nm_modem_get_control_port (NMModem *modem); const char *nm_modem_get_data_port (NMModem *modem); const char *nm_modem_get_driver (NMModem *modem); +gboolean nm_modem_get_iid (NMModem *modem, NMUtilsIPv6IfaceId *out_iid); gboolean nm_modem_owns_port (NMModem *modem, const char *iface); @@ -182,8 +206,7 @@ NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem, NMDeviceStateReason *reason); NMActStageReturn nm_modem_stage3_ip6_config_start (NMModem *modem, - NMDevice *device, - NMDeviceClass *device_class, + NMActRequest *req, NMDeviceStateReason *reason); void nm_modem_ip4_pre_commit (NMModem *modem, NMDevice *device, NMIP4Config *config); @@ -209,9 +232,20 @@ void nm_modem_set_state (NMModem *self, void nm_modem_set_prev_state (NMModem *self, const char *reason); const char * nm_modem_state_to_string (NMModemState state); +NMModemIPType nm_modem_get_supported_ip_types (NMModem *self); + /* For the modem-manager only */ void nm_modem_emit_removed (NMModem *self); +NMModemIPType nm_modem_get_connection_ip_type (NMModem *self, + NMConnection *connection, + GError **error); + +/* For subclasses */ +void nm_modem_emit_ip6_config_result (NMModem *self, + NMIP6Config *config, + GError *error); + G_END_DECLS -#endif /* NM_MODEM_H */ +#endif /* __NETWORKMANAGER_MODEM_H__ */ diff --git a/src/devices/wwan/nm-wwan-factory.c b/src/devices/wwan/nm-wwan-factory.c index b1e2307e..2b9c3d4d 100644 --- a/src/devices/wwan/nm-wwan-factory.c +++ b/src/devices/wwan/nm-wwan-factory.c @@ -18,10 +18,11 @@ * Copyright (C) 2014 Red Hat, Inc. */ +#include "config.h" + #include #include -#include "config.h" #include "nm-device-factory.h" #include "nm-wwan-factory.h" #include "nm-modem-manager.h" @@ -43,20 +44,12 @@ typedef struct { /************************************************************************/ -#define PLUGIN_TYPE NM_DEVICE_TYPE_MODEM - G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { return (NMDeviceFactory *) g_object_new (NM_TYPE_WWAN_FACTORY, NULL); } -G_MODULE_EXPORT NMDeviceType -nm_device_factory_get_device_type (void) -{ - return PLUGIN_TYPE; -} - /************************************************************************/ static void @@ -93,9 +86,17 @@ modem_added_cb (NMModemManager *manager, g_object_unref (device); } + +static NMDeviceType +get_device_type (NMDeviceFactory *factory) +{ + return NM_DEVICE_TYPE_MODEM; +} + static void -nm_wwan_factory_init (NMWwanFactory *self) +start (NMDeviceFactory *factory) { + NMWwanFactory *self = NM_WWAN_FACTORY (factory); NMWwanFactoryPrivate *priv = NM_WWAN_FACTORY_GET_PRIVATE (self); priv->mm = g_object_new (NM_TYPE_MODEM_MANAGER, NULL); @@ -106,9 +107,16 @@ nm_wwan_factory_init (NMWwanFactory *self) self); } +static void +nm_wwan_factory_init (NMWwanFactory *self) +{ +} + static void device_factory_interface_init (NMDeviceFactory *factory_iface) { + factory_iface->get_device_type = get_device_type; + factory_iface->start = start; } static void diff --git a/src/devices/wwan/nm-wwan-factory.h b/src/devices/wwan/nm-wwan-factory.h index b7aee01f..c6c03f1f 100644 --- a/src/devices/wwan/nm-wwan-factory.h +++ b/src/devices/wwan/nm-wwan-factory.h @@ -18,8 +18,8 @@ * Copyright (C) 2014 Red Hat, Inc. */ -#ifndef NM_WWAN_FACTORY_H -#define NM_WWAN_FACTORY_H +#ifndef __NETWORKMANAGER_WWAN_FACTORY_H__ +#define __NETWORKMANAGER_WWAN_FACTORY_H__ #include @@ -34,4 +34,4 @@ typedef struct { GObjectClass parent; } NMWwanFactoryClass; -#endif /* NM_WWAN_FACTORY_H */ +#endif /* __NETWORKMANAGER_WWAN_FACTORY_H__ */ diff --git a/src/devices/wwan/wwan-exports.ver b/src/devices/wwan/wwan-exports.ver index dc505d17..c23ab24b 100644 --- a/src/devices/wwan/wwan-exports.ver +++ b/src/devices/wwan/wwan-exports.ver @@ -6,11 +6,11 @@ global: nm_modem_complete_connection; nm_modem_deactivate; nm_modem_device_state_changed; - nm_modem_error_quark; nm_modem_get_capabilities; nm_modem_get_control_port; nm_modem_get_data_port; nm_modem_get_driver; + nm_modem_get_iid; nm_modem_get_path; nm_modem_get_secrets; nm_modem_get_state; diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am index 63eac9d5..27945f55 100644 --- a/src/dhcp-manager/Makefile.am +++ b/src/dhcp-manager/Makefile.am @@ -3,15 +3,15 @@ libexec_PROGRAMS = nm-dhcp-helper nm_dhcp_helper_SOURCES = nm-dhcp-helper.c nm_dhcp_helper_CPPFLAGS = \ - $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DNMRUNDIR=\"$(nmrundir)\" -nm_dhcp_helper_LDADD = $(DBUS_LIBS) +nm_dhcp_helper_LDADD = $(GLIB_LIBS) -# FIXME: remove when dbus-glib >= 0.100 is required +# FIXME: remove when dbus-glib >= 0.100 or GDBus is required dhcp_helper_conf = nm-dhcp-helper.conf if !HAVE_DBUS_GLIB_100 diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in index 5495b12f..4dea1085 100644 --- a/src/dhcp-manager/Makefile.in +++ b/src/dhcp-manager/Makefile.in @@ -212,6 +212,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -335,6 +337,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -354,6 +357,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -380,7 +384,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -461,14 +465,14 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ nm_dhcp_helper_SOURCES = nm-dhcp-helper.c nm_dhcp_helper_CPPFLAGS = \ - $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ -DG_LOG_DOMAIN=\""nm-dhcp-helper"\" \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DNMRUNDIR=\"$(nmrundir)\" -nm_dhcp_helper_LDADD = $(DBUS_LIBS) +nm_dhcp_helper_LDADD = $(GLIB_LIBS) -# FIXME: remove when dbus-glib >= 0.100 is required +# FIXME: remove when dbus-glib >= 0.100 or GDBus is required dhcp_helper_conf = nm-dhcp-helper.conf @HAVE_DBUS_GLIB_100_FALSE@dbusservicedir = $(DBUS_SYS_DIR) @HAVE_DBUS_GLIB_100_FALSE@dbusservice_DATA = $(dhcp_helper_conf) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 03c11c74..47fa5317 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -17,7 +17,8 @@ * */ -#include +#include "config.h" + #include #include #include @@ -33,35 +34,35 @@ #include "nm-logging.h" #include "nm-dbus-glib-types.h" #include "nm-dhcp-client.h" +#include "nm-dhcp-utils.h" +#include "nm-platform.h" typedef struct { char * iface; + int ifindex; GByteArray * hwaddr; gboolean ipv6; char * uuid; - guint priority; + guint32 priority; guint32 timeout; GByteArray * duid; + GBytes * client_id; + char * hostname; - guchar state; - GPid pid; - gboolean dead; + NMDhcpState state; + pid_t pid; guint timeout_id; guint watch_id; - guint32 remove_id; - GHashTable * options; gboolean info_only; -} NMDHCPClientPrivate; +} NMDhcpClientPrivate; -#define NM_DHCP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_CLIENT, NMDHCPClientPrivate)) +#define NM_DHCP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_CLIENT, NMDhcpClientPrivate)) -G_DEFINE_TYPE_EXTENDED (NMDHCPClient, nm_dhcp_client, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, {}) +G_DEFINE_TYPE_EXTENDED (NMDhcpClient, nm_dhcp_client, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, {}) enum { SIGNAL_STATE_CHANGED, - SIGNAL_TIMEOUT, - SIGNAL_REMOVE, LAST_SIGNAL }; @@ -70,6 +71,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, PROP_IFACE, + PROP_IFINDEX, PROP_HWADDR, PROP_IPV6, PROP_UUID, @@ -80,8 +82,8 @@ enum { /********************************************/ -GPid -nm_dhcp_client_get_pid (NMDHCPClient *self) +pid_t +nm_dhcp_client_get_pid (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), -1); @@ -89,15 +91,23 @@ nm_dhcp_client_get_pid (NMDHCPClient *self) } const char * -nm_dhcp_client_get_iface (NMDHCPClient *self) +nm_dhcp_client_get_iface (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); return NM_DHCP_CLIENT_GET_PRIVATE (self)->iface; } +int +nm_dhcp_client_get_ifindex (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), -1); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->ifindex; +} + gboolean -nm_dhcp_client_get_ipv6 (NMDHCPClient *self) +nm_dhcp_client_get_ipv6 (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); @@ -105,19 +115,120 @@ nm_dhcp_client_get_ipv6 (NMDHCPClient *self) } const char * -nm_dhcp_client_get_uuid (NMDHCPClient *self) +nm_dhcp_client_get_uuid (NMDhcpClient *self) { g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); return NM_DHCP_CLIENT_GET_PRIVATE (self)->uuid; } +const GByteArray * +nm_dhcp_client_get_duid (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->duid; +} + +const GByteArray * +nm_dhcp_client_get_hw_addr (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->hwaddr; +} + +guint32 +nm_dhcp_client_get_priority (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), G_MAXUINT32); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->priority; +} + +GBytes * +nm_dhcp_client_get_client_id (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->client_id; +} + +void +nm_dhcp_client_set_client_id (NMDhcpClient *self, GBytes *client_id) +{ + NMDhcpClientPrivate *priv; + + g_return_if_fail (NM_IS_DHCP_CLIENT (self)); + + priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + + if (priv->client_id && client_id && g_bytes_equal (priv->client_id, client_id)) + return; + g_clear_pointer (&priv->client_id, g_bytes_unref); + priv->client_id = client_id ? g_bytes_ref (client_id) : NULL; +} + +const char * +nm_dhcp_client_get_hostname (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->hostname; +} + +/********************************************/ + +static const char *state_table[NM_DHCP_STATE_MAX + 1] = { + [NM_DHCP_STATE_UNKNOWN] = "unknown", + [NM_DHCP_STATE_BOUND] = "bound", + [NM_DHCP_STATE_TIMEOUT] = "timeout", + [NM_DHCP_STATE_EXPIRE] = "expire", + [NM_DHCP_STATE_DONE] = "done", + [NM_DHCP_STATE_FAIL] = "fail", +}; + +static const char * +state_to_string (NMDhcpState state) +{ + if ((gsize) state < G_N_ELEMENTS (state_table)) + return state_table[state]; + return NULL; +} + +static NMDhcpState +reason_to_state (const char *iface, const char *reason) +{ + if (g_ascii_strcasecmp (reason, "bound") == 0 || + g_ascii_strcasecmp (reason, "bound6") == 0 || + g_ascii_strcasecmp (reason, "renew") == 0 || + g_ascii_strcasecmp (reason, "renew6") == 0 || + g_ascii_strcasecmp (reason, "reboot") == 0 || + g_ascii_strcasecmp (reason, "rebind") == 0 || + g_ascii_strcasecmp (reason, "rebind6") == 0) + return NM_DHCP_STATE_BOUND; + else if (g_ascii_strcasecmp (reason, "timeout") == 0) + return NM_DHCP_STATE_TIMEOUT; + else if (g_ascii_strcasecmp (reason, "nak") == 0 || + g_ascii_strcasecmp (reason, "expire") == 0 || + g_ascii_strcasecmp (reason, "expire6") == 0) + return NM_DHCP_STATE_EXPIRE; + else if (g_ascii_strcasecmp (reason, "end") == 0) + return NM_DHCP_STATE_DONE; + else if (g_ascii_strcasecmp (reason, "fail") == 0 || + g_ascii_strcasecmp (reason, "abend") == 0) + return NM_DHCP_STATE_FAIL; + + nm_log_dbg (LOGD_DHCP, "(%s): unmapped DHCP state '%s'", iface, reason); + return NM_DHCP_STATE_UNKNOWN; +} + /********************************************/ static void -timeout_cleanup (NMDHCPClient *self) +timeout_cleanup (NMDhcpClient *self) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); if (priv->timeout_id) { g_source_remove (priv->timeout_id); @@ -126,9 +237,9 @@ timeout_cleanup (NMDHCPClient *self) } static void -watch_cleanup (NMDHCPClient *self) +watch_cleanup (NMDhcpClient *self) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); if (priv->watch_id) { g_source_remove (priv->watch_id); @@ -137,171 +248,158 @@ watch_cleanup (NMDHCPClient *self) } void -nm_dhcp_client_stop_pid (GPid pid, const char *iface) +nm_dhcp_client_stop_pid (pid_t pid, const char *iface) { - int i = 5; /* roughly 0.5 seconds */ - - g_return_if_fail (pid > 0); - - /* Tell it to quit; maybe it wants to send out a RELEASE message */ - kill (pid, SIGTERM); - - while (i-- > 0) { - gint child_status; - int ret; + char *name = iface ? g_strdup_printf ("dhcp-client-%s", iface) : NULL; - ret = waitpid (pid, &child_status, WNOHANG); - if (ret > 0) - break; + g_return_if_fail (pid > 1); - if (ret == -1) { - /* Child already exited */ - if (errno == ECHILD) { - /* Was it really our child and it exited? */ - if (kill (pid, 0) < 0 && errno == ESRCH) - break; - } else { - /* Took too long; shoot it in the head */ - i = 0; - break; - } - } - g_usleep (G_USEC_PER_SEC / 10); - } - - if (i <= 0) { - if (iface) { - nm_log_warn (LOGD_DHCP, "(%s): DHCP client pid %d didn't exit, will kill it.", - iface, pid); - } - kill (pid, SIGKILL); - - nm_log_dbg (LOGD_DHCP, "waiting for DHCP client pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_DHCP, "DHCP client pid %d cleaned up", pid); - } + nm_utils_kill_child_sync (pid, SIGTERM, LOGD_DHCP, name ? name : "dhcp-client", NULL, + 1000 / 2, 1000 / 20); + g_free (name); } static void -stop (NMDHCPClient *self, gboolean release, const GByteArray *duid) +stop (NMDhcpClient *self, gboolean release, const GByteArray *duid) { - NMDHCPClientPrivate *priv; + NMDhcpClientPrivate *priv; g_return_if_fail (NM_IS_DHCP_CLIENT (self)); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - g_return_if_fail (priv->pid > 0); - - /* Clean up the watch handler since we're explicitly killing the daemon */ - watch_cleanup (self); - - nm_dhcp_client_stop_pid (priv->pid, priv->iface); + if (priv->pid > 0) { + /* Clean up the watch handler since we're explicitly killing the daemon */ + watch_cleanup (self); + nm_dhcp_client_stop_pid (priv->pid, priv->iface); + } + priv->pid = -1; priv->info_only = FALSE; } -static gboolean -daemon_timeout (gpointer user_data) +void +nm_dhcp_client_set_state (NMDhcpClient *self, + NMDhcpState new_state, + GObject *ip_config, + GHashTable *options) { - NMDHCPClient *self = NM_DHCP_CLIENT (user_data); - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - if (priv->ipv6) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 request timed out.", priv->iface); + if (new_state >= NM_DHCP_STATE_BOUND) + timeout_cleanup (self); + if (new_state >= NM_DHCP_STATE_TIMEOUT) + watch_cleanup (self); + + if (new_state == NM_DHCP_STATE_BOUND) { + g_assert ( (priv->ipv6 && NM_IS_IP6_CONFIG (ip_config)) + || (!priv->ipv6 && NM_IS_IP4_CONFIG (ip_config))); + g_assert (options); + g_assert_cmpint (g_hash_table_size (options), >, 0); } else { - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 request timed out.", priv->iface); + g_assert (ip_config == NULL); + g_assert (options == NULL); } - g_signal_emit (G_OBJECT (self), signals[SIGNAL_TIMEOUT], 0); - return FALSE; -} -static gboolean -signal_remove (gpointer user_data) -{ - NMDHCPClient *self = NM_DHCP_CLIENT (user_data); + /* The client may send same-state transitions for RENEW/REBIND events and + * the lease may have changed, so handle same-state transitions for the + * BOUND state. Ignore same-state transitions for other events since + * the lease won't have changed and the state was already handled. + */ + if ((priv->state == new_state) && (new_state != NM_DHCP_STATE_BOUND)) + return; - NM_DHCP_CLIENT_GET_PRIVATE (self)->remove_id = 0; - g_signal_emit (G_OBJECT (self), signals[SIGNAL_REMOVE], 0); - return FALSE; + nm_log_info (priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): DHCPv%c state changed %s -> %s", + priv->iface, + priv->ipv6 ? '6' : '4', + state_to_string (priv->state), + state_to_string (new_state)); + + priv->state = new_state; + g_signal_emit (G_OBJECT (self), + signals[SIGNAL_STATE_CHANGED], 0, + new_state, + ip_config, + options); } -static void -dhcp_client_set_state (NMDHCPClient *self, - NMDHCPState state, - gboolean emit_state, - gboolean remove_now) +static gboolean +daemon_timeout (gpointer user_data) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClient *self = NM_DHCP_CLIENT (user_data); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - priv->state = state; - - if (emit_state) - g_signal_emit (G_OBJECT (self), signals[SIGNAL_STATE_CHANGED], 0, priv->state); - - if (state == DHC_END || state == DHC_ABEND) { - /* Start the remove signal timer */ - if (remove_now) { - g_signal_emit (G_OBJECT (self), signals[SIGNAL_REMOVE], 0); - } else { - if (!priv->remove_id) - priv->remove_id = g_timeout_add_seconds (5, signal_remove, self); - } - } + priv->timeout_id = 0; + nm_log_warn (priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): DHCPv%c request timed out.", + priv->iface, + priv->ipv6 ? '6' : '4'); + nm_dhcp_client_set_state (self, NM_DHCP_STATE_TIMEOUT, NULL, NULL); + return G_SOURCE_REMOVE; } static void daemon_watch_cb (GPid pid, gint status, gpointer user_data) { - NMDHCPClient *self = NM_DHCP_CLIENT (user_data); - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - NMDHCPState new_state; - - if (priv->ipv6) { - nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 client pid %d exited with status %d", - priv->iface, pid, - WIFEXITED (status) ? WEXITSTATUS (status) : -1); - } else { - nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 client pid %d exited with status %d", - priv->iface, pid, - WIFEXITED (status) ? WEXITSTATUS (status) : -1); - } - - if (!WIFEXITED (status)) { - new_state = DHC_ABEND; + NMDhcpClient *self = NM_DHCP_CLIENT (user_data); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpState new_state; + guint64 log_domain; + guint ip_ver; + + log_domain = priv->ipv6 ? LOGD_DHCP6 : LOGD_DHCP4; + ip_ver = priv->ipv6 ? 6 : 4; + + if (WIFEXITED (status)) + nm_log_info (log_domain, "(%s): DHCPv%d client pid %d exited with status %d", + priv->iface, ip_ver, pid, WEXITSTATUS (status)); + else if (WIFSIGNALED (status)) + nm_log_info (log_domain, "(%s): DHCPv%d client pid %d killed by signal %d", + priv->iface, ip_ver, pid, WTERMSIG (status)); + else if (WIFSTOPPED(status)) + nm_log_info (log_domain, "(%s): DHCPv%d client pid %d stopped by signal %d", + priv->iface, ip_ver, pid, WSTOPSIG (status)); + else if (WIFCONTINUED (status)) + nm_log_info (log_domain, "(%s): DHCPv%d client pid %d resumed (by SIGCONT)", + priv->iface, ip_ver, pid); + else nm_log_warn (LOGD_DHCP, "DHCP client died abnormally"); - } else - new_state = DHC_END; - watch_cleanup (self); - timeout_cleanup (self); - priv->dead = TRUE; + if (!WIFEXITED (status)) + new_state = NM_DHCP_STATE_FAIL; + else + new_state = NM_DHCP_STATE_DONE; + + priv->pid = -1; - dhcp_client_set_state (self, new_state, TRUE, FALSE); + nm_dhcp_client_set_state (self, new_state, NULL, NULL); } -static void -start_monitor (NMDHCPClient *self) +void +nm_dhcp_client_watch_child (NMDhcpClient *self, pid_t pid) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - g_return_if_fail (priv->pid > 0); + g_return_if_fail (priv->pid == -1); + priv->pid = pid; /* Set up a timeout on the transaction to kill it after the timeout */ + g_assert (priv->timeout_id == 0); priv->timeout_id = g_timeout_add_seconds (priv->timeout, daemon_timeout, self); - priv->watch_id = g_child_watch_add (priv->pid, - (GChildWatchFunc) daemon_watch_cb, - self); + g_assert (priv->watch_id == 0); + priv->watch_id = g_child_watch_add (pid, daemon_watch_cb, self); } gboolean -nm_dhcp_client_start_ip4 (NMDHCPClient *self, +nm_dhcp_client_start_ip4 (NMDhcpClient *self, const char *dhcp_client_id, - GByteArray *dhcp_anycast_addr, - const char *hostname) + const char *dhcp_anycast_addr, + const char *hostname, + const char *last_ip4_address) { - NMDHCPClientPrivate *priv; + NMDhcpClientPrivate *priv; g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); @@ -313,11 +411,12 @@ nm_dhcp_client_start_ip4 (NMDHCPClient *self, nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv4 transaction (timeout in %d seconds)", priv->iface, priv->timeout); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_client_id, dhcp_anycast_addr, hostname); - if (priv->pid) - start_monitor (self); + nm_dhcp_client_set_client_id (self, dhcp_client_id ? nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id) : NULL); - return priv->pid ? TRUE : FALSE; + g_clear_pointer (&priv->hostname, g_free); + priv->hostname = g_strdup (hostname); + + return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address); } /* uuid_parse does not work for machine-id, so we use our own converter */ @@ -406,38 +505,21 @@ generate_duid_from_machine_id (void) return duid; } -static char * -escape_duid (const GByteArray *duid) -{ - guint32 i = 0; - GString *s; - - g_return_val_if_fail (duid != NULL, NULL); - - s = g_string_sized_new (40); - while (i < duid->len) { - if (s->len) - g_string_append_c (s, ':'); - g_string_append_printf (s, "%02x", duid->data[i++]); - } - return g_string_free (s, FALSE); -} - static GByteArray * -get_duid (NMDHCPClient *self) +get_duid (NMDhcpClient *self) { static GByteArray *duid = NULL; GByteArray *copy = NULL; - char *escaped; + char *str; if (G_UNLIKELY (duid == NULL)) { duid = generate_duid_from_machine_id (); g_assert (duid); if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP6)) { - escaped = escape_duid (duid); - nm_log_dbg (LOGD_DHCP6, "Generated DUID %s", escaped); - g_free (escaped); + str = nm_dhcp_utils_duid_to_string (duid); + nm_log_dbg (LOGD_DHCP6, "Generated DUID %s", str); + g_free (str); } } @@ -450,13 +532,14 @@ get_duid (NMDHCPClient *self) } gboolean -nm_dhcp_client_start_ip6 (NMDHCPClient *self, - GByteArray *dhcp_anycast_addr, +nm_dhcp_client_start_ip6 (NMDhcpClient *self, + const char *dhcp_anycast_addr, const char *hostname, - gboolean info_only) + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy) { - NMDHCPClientPrivate *priv; - char *escaped; + NMDhcpClientPrivate *priv; + char *str; g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); @@ -472,25 +555,24 @@ nm_dhcp_client_start_ip6 (NMDHCPClient *self, priv->duid = NM_DHCP_CLIENT_GET_CLASS (self)->get_duid (self); if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP)) { - escaped = escape_duid (priv->duid); - nm_log_dbg (LOGD_DHCP, "(%s): DHCPv6 DUID is '%s'", priv->iface, escaped); - g_free (escaped); + str = nm_dhcp_utils_duid_to_string (priv->duid); + nm_log_dbg (LOGD_DHCP, "(%s): DHCPv6 DUID is '%s'", priv->iface, str); + g_free (str); } + g_clear_pointer (&priv->hostname, g_free); + priv->hostname = g_strdup (hostname); + priv->info_only = info_only; nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv6 transaction (timeout in %d seconds)", priv->iface, priv->timeout); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, - dhcp_anycast_addr, - hostname, - info_only, - priv->duid); - if (priv->pid > 0) - start_monitor (self); - - return priv->pid ? TRUE : FALSE; + return NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, + dhcp_anycast_addr, + info_only, + privacy, + priv->duid); } void @@ -506,11 +588,14 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) errno = 0; tmp = strtol (pid_contents, NULL, 10); if ((errno == 0) && (tmp > 1)) { + guint64 start_time; const char *exe; /* Ensure the process is a DHCP client */ + start_time = nm_utils_get_start_time_for_pid (tmp); proc_path = g_strdup_printf ("/proc/%ld/cmdline", tmp); - if (g_file_get_contents (proc_path, &proc_contents, NULL, NULL)) { + if ( start_time + && g_file_get_contents (proc_path, &proc_contents, NULL, NULL)) { exe = strrchr (proc_contents, '/'); if (exe) exe++; @@ -518,7 +603,8 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) exe = proc_contents; if (!strcmp (exe, binary_name)) - nm_dhcp_client_stop_pid ((GPid) tmp, NULL); + nm_utils_kill_process_sync (tmp, start_time, SIGTERM, LOGD_DHCP, + "dhcp-client", 1000 / 2, 1000 / 20); } } @@ -531,103 +617,30 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) } void -nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) +nm_dhcp_client_stop (NMDhcpClient *self, gboolean release) { - NMDHCPClientPrivate *priv; + NMDhcpClientPrivate *priv; + pid_t old_pid = 0; g_return_if_fail (NM_IS_DHCP_CLIENT (self)); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); /* Kill the DHCP client */ - if (!priv->dead) { - NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release, priv->duid); - priv->dead = TRUE; - + old_pid = priv->pid; + NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release, priv->duid); + if (old_pid > 0) { nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d", - priv->iface, priv->pid); - } - - /* And clean stuff up */ - - priv->pid = -1; - dhcp_client_set_state (self, DHC_END, FALSE, TRUE); - - g_hash_table_remove_all (priv->options); + priv->iface, old_pid); + } else + nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction", priv->iface); + g_assert (priv->pid == -1); - timeout_cleanup (self); - watch_cleanup (self); + nm_dhcp_client_set_state (self, NM_DHCP_STATE_DONE, NULL, NULL); } /********************************************/ -static gboolean -state_is_bound (guint32 state) -{ - if ( (state == DHC_BOUND4) - || (state == DHC_BOUND6) - || (state == DHC_RENEW4) - || (state == DHC_RENEW6) - || (state == DHC_REBOOT) - || (state == DHC_REBIND4) - || (state == DHC_REBIND6) - || (state == DHC_IPV4LL)) - return TRUE; - - return FALSE; -} - -static const char *state_table[] = { - [DHC_NBI] = "nbi", - [DHC_PREINIT] = "preinit", - [DHC_PREINIT6] = "preinit6", - [DHC_BOUND4] = "bound", - [DHC_BOUND6] = "bound6", - [DHC_IPV4LL] = "ipv4ll", - [DHC_RENEW4] = "renew", - [DHC_RENEW6] = "renew6", - [DHC_REBOOT] = "reboot", - [DHC_REBIND4] = "rebind", - [DHC_REBIND6] = "rebind6", - [DHC_DEPREF6] = "depref6", - [DHC_STOP] = "stop", - [DHC_STOP6] = "stop6", - [DHC_MEDIUM] = "medium", - [DHC_TIMEOUT] = "timeout", - [DHC_FAIL] = "fail", - [DHC_EXPIRE] = "expire", - [DHC_EXPIRE6] = "expire6", - [DHC_RELEASE] = "release", - [DHC_RELEASE6] = "release6", - [DHC_START] = "start", - [DHC_ABEND] = "abend", - [DHC_END] = "end", -}; - -static const char * -state_to_string (NMDHCPState state) -{ - if (state >= 0 && state < G_N_ELEMENTS (state_table)) - return state_table[state]; - return NULL; -} - -static NMDHCPState -string_to_state (const char *name) -{ - int i; - - if (name) { - for (i = 0; i < G_N_ELEMENTS (state_table); i++) { - const char *n = state_table[i]; - - if (n && !strcasecmp (name, n)) - return i; - } - } - return 255; -} - static char * garray_to_string (GArray *array, const char *key) { @@ -661,848 +674,133 @@ garray_to_string (GArray *array, const char *key) return converted; } +#define OLD_TAG "old_" +#define NEW_TAG "new_" + static void -copy_option (gpointer key, - gpointer value, +copy_option (const char * key, + GValue *value, gpointer user_data) { GHashTable *hash = user_data; - const char *str_key = (const char *) key; char *str_value = NULL; + const char **p; + static const char *ignored_keys[] = { + "interface", + "pid", + "reason", + "dhcp_message_type", + NULL + }; - if (G_VALUE_TYPE (value) != DBUS_TYPE_G_UCHAR_ARRAY) { - nm_log_warn (LOGD_DHCP, "unexpected key %s value type was not " - "DBUS_TYPE_G_UCHAR_ARRAY", - str_key); + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)) { + nm_log_warn (LOGD_DHCP, "key %s value type was not DBUS_TYPE_G_UCHAR_ARRAY", key); return; } - str_value = garray_to_string ((GArray *) g_value_get_boxed (value), str_key); - if (str_value) - g_hash_table_insert (hash, g_strdup (str_key), str_value); -} - -void -nm_dhcp_client_new_options (NMDHCPClient *self, - GHashTable *options, - const char *reason) -{ - NMDHCPClientPrivate *priv; - guint32 old_state; - guint32 new_state; - - g_return_if_fail (NM_IS_DHCP_CLIENT (self)); - g_return_if_fail (options != NULL); - g_return_if_fail (reason != NULL); + if (g_str_has_prefix (key, OLD_TAG)) + return; - priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - old_state = priv->state; - new_state = string_to_state (reason); - - /* Clear old and save new DHCP options */ - g_hash_table_remove_all (priv->options); - g_hash_table_foreach (options, copy_option, priv->options); - - if (old_state == new_state) { - /* dhclient will stay in the same state (or, really, provide the same - * reason) for operations like RENEW and REBIND. We need to ensure - * that triggers various DHCP lease change code, so we need to pass - * along same-state transitions for these states. - */ - if ( new_state != DHC_BOUND4 - && new_state != DHC_RENEW4 - && new_state != DHC_REBIND4 - && new_state != DHC_BOUND6 - && new_state != DHC_RENEW6 - && new_state != DHC_REBIND6) + /* Filter out stuff that's not actually new DHCP options */ + for (p = ignored_keys; *p; p++) { + if (!strcmp (*p, key)) return; } - /* Handle changed device state */ - if (state_is_bound (new_state)) { - /* Cancel the timeout if the DHCP client is now bound */ - timeout_cleanup (self); - } - - if (priv->ipv6) { - nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 state changed %s -> %s", - priv->iface, - state_to_string (old_state), - state_to_string (new_state)); - } else { - nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 state changed %s -> %s", - priv->iface, - state_to_string (old_state), - state_to_string (new_state)); - } + if (g_str_has_prefix (key, NEW_TAG)) + key += STRLEN (NEW_TAG); + if (!key[0]) + return; - dhcp_client_set_state (self, new_state, TRUE, FALSE); + str_value = garray_to_string ((GArray *) g_value_get_boxed (value), key); + if (str_value) + g_hash_table_insert (hash, g_strdup (key), str_value); } -#define NEW_TAG "new_" -#define OLD_TAG "old_" - gboolean -nm_dhcp_client_foreach_option (NMDHCPClient *self, - GHFunc func, - gpointer user_data) -{ - NMDHCPClientPrivate *priv; - GHashTableIter iter; - gpointer iterkey, itervalue; +nm_dhcp_client_handle_event (gpointer unused, + const char *iface, + gint pid, + GHashTable *options, + const char *reason, + NMDhcpClient *self) +{ + NMDhcpClientPrivate *priv; + guint32 old_state; + guint32 new_state; + GHashTable *str_options = NULL; + GObject *ip_config = NULL; g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - - if (!state_is_bound (priv->state)) { - if (priv->ipv6) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); - } else { - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface); - } - } - - g_hash_table_iter_init (&iter, priv->options); - while (g_hash_table_iter_next (&iter, &iterkey, &itervalue)) { - const char *key = iterkey, *value = itervalue; - const char **p; - static const char *filter_options[] = { - "interface", "pid", "reason", "dhcp_message_type", NULL - }; - gboolean ignore = FALSE; - - /* Filter out stuff that's not actually new DHCP options */ - for (p = filter_options; *p; p++) { - if (!strcmp (*p, key) || !strncmp (key, OLD_TAG, strlen (OLD_TAG))) { - ignore = TRUE; - break; - } - } - - if (!ignore) { - const char *tmp_key = key; - - /* Remove the "new_" prefix that dhclient passes back */ - if (!strncmp (key, NEW_TAG, strlen (NEW_TAG))) - tmp_key = key + strlen (NEW_TAG); - - func ((gpointer) tmp_key, (gpointer) value, user_data); - } - } - return TRUE; -} - -/********************************************/ - -static gboolean -ip4_process_dhcpcd_rfc3442_routes (NMDHCPClient *self, - const char *str, - NMIP4Config *ip4_config, - guint32 *gwaddr) -{ - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - char **routes, **r; - gboolean have_routes = FALSE; - - routes = g_strsplit (str, " ", 0); - if (g_strv_length (routes) == 0) - goto out; - - if ((g_strv_length (routes) % 2) != 0) { - nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid"); - goto out; - } - - for (r = routes; *r; r += 2) { - char *slash; - NMPlatformIP4Route route; - int rt_cidr = 32; - guint32 rt_addr, rt_route; - - slash = strchr(*r, '/'); - if (slash) { - *slash = '\0'; - errno = 0; - rt_cidr = strtol (slash + 1, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1); - continue; - } - } - if (inet_pton (AF_INET, *r, &rt_addr) <= 0) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r); - continue; - } - if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) { - nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1)); - continue; - } - - have_routes = TRUE; - if (rt_cidr == 0 && rt_addr == 0) { - /* FIXME: how to handle multiple routers? */ - *gwaddr = rt_route; - } else { - nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1)); - memset (&route, 0, sizeof (route)); - route.network = rt_addr; - route.plen = rt_cidr; - route.gateway = rt_route; - route.source = NM_PLATFORM_SOURCE_DHCP; - route.metric = priv->priority; - nm_ip4_config_add_route (ip4_config, &route); - } - } - -out: - g_strfreev (routes); - return have_routes; -} - -static const char ** -process_dhclient_rfc3442_route (const char **octets, NMPlatformIP4Route *route, gboolean *success) -{ - const char **o = octets; - int addr_len = 0, i = 0; - long int tmp; - char *next_hop; - guint32 tmp_addr; - - *success = FALSE; - - if (!*o) - return o; /* no prefix */ - - tmp = strtol (*o, NULL, 10); - if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */ - return o; - - memset (route, 0, sizeof (*route)); - route->plen = tmp; - o++; - - if (tmp > 0) - addr_len = ((tmp - 1) / 8) + 1; - - /* ensure there's at least the address + next hop left */ - if (g_strv_length ((char **) o) < addr_len + 4) - goto error; - - if (tmp) { - const char *addr[4] = { "0", "0", "0", "0" }; - char *str_addr; - - for (i = 0; i < addr_len; i++) - addr[i] = *o++; - - str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL); - if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) { - g_free (str_addr); - goto error; - } - tmp_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp); - route->network = tmp_addr; - } - - /* Handle next hop */ - next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL); - if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) { - g_free (next_hop); - goto error; - } - route->gateway = tmp_addr; - g_free (next_hop); - - *success = TRUE; - return o + 4; /* advance to past the next hop */ - -error: - return o; -} - -static gboolean -ip4_process_dhclient_rfc3442_routes (NMDHCPClient *self, - const char *str, - NMIP4Config *ip4_config, - guint32 *gwaddr) -{ - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - char **octets, **o; - gboolean have_routes = FALSE; - NMPlatformIP4Route route; - gboolean success; - - o = octets = g_strsplit_set (str, " .", 0); - if (g_strv_length (octets) < 5) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); - goto out; - } - - while (*o) { - memset (&route, 0, sizeof (route)); - o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success); - if (!success) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes"); - break; - } - - have_routes = TRUE; - if (!route.plen) { - /* gateway passed as classless static route */ - *gwaddr = route.gateway; - } else { - char addr[INET_ADDRSTRLEN]; - - /* normal route */ - route.source = NM_PLATFORM_SOURCE_DHCP; - route.metric = priv->priority; - nm_ip4_config_add_route (ip4_config, &route); - - nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", - nm_utils_inet4_ntop (route.network, addr), route.plen, - nm_utils_inet4_ntop (route.gateway, NULL)); - } - } - -out: - g_strfreev (octets); - return have_routes; -} - -static gboolean -ip4_process_classless_routes (NMDHCPClient *self, - GHashTable *options, - NMIP4Config *ip4_config, - guint32 *gwaddr) -{ - const char *str, *p; - + g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (pid > 0, FALSE); g_return_val_if_fail (options != NULL, FALSE); - g_return_val_if_fail (ip4_config != NULL, FALSE); - - *gwaddr = 0; - - /* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a - * slightly different format: - * - * option classless-static-routes = array of (destination-descriptor ip-address); - * - * which results in: - * - * 0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6 - * - * dhcpcd supports classless static routes natively and uses this same - * option identifier with the following format: - * - * 192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41 - */ - str = g_hash_table_lookup (options, "new_classless_static_routes"); - - /* dhclient doesn't have actual support for rfc3442 classless static routes - * upstream. Thus, people resort to defining the option in dhclient.conf - * and using arbitrary formats like so: - * - * option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; - * - * See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html - */ - if (!str) - str = g_hash_table_lookup (options, "new_rfc3442_classless_static_routes"); - - /* Microsoft version; same as rfc3442 but with a different option # (249) */ - if (!str) - str = g_hash_table_lookup (options, "new_ms_classless_static_routes"); - - if (!str || !strlen (str)) - return FALSE; - - p = str; - while (*p) { - if (!g_ascii_isdigit (*p) && (*p != ' ') && (*p != '.') && (*p != '/')) { - nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); - return FALSE; - } - p++; - }; - - if (strchr (str, '/')) { - /* dhcpcd format */ - return ip4_process_dhcpcd_rfc3442_routes (self, str, ip4_config, gwaddr); - } - - return ip4_process_dhclient_rfc3442_routes (self, str, ip4_config, gwaddr); -} - -static void -process_classful_routes (NMDHCPClient *self, GHashTable *options, NMIP4Config *ip4_config) -{ - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - const char *str; - char **searches, **s; - - str = g_hash_table_lookup (options, "new_static_routes"); - if (!str) - return; - - searches = g_strsplit (str, " ", 0); - if ((g_strv_length (searches) % 2)) { - nm_log_info (LOGD_DHCP, " static routes provided, but invalid"); - goto out; - } - - for (s = searches; *s; s += 2) { - NMPlatformIP4Route route; - guint32 rt_addr, rt_route; - - if (inet_pton (AF_INET, *s, &rt_addr) <= 0) { - nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route address: '%s'", *s); - continue; - } - if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) { - nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route gateway: '%s'", *(s + 1)); - continue; - } - - // FIXME: ensure the IP address and route are sane - - memset (&route, 0, sizeof (route)); - route.network = rt_addr; - /* RFC 2132, updated by RFC 3442: - The Static Routes option (option 33) does not provide a subnet mask - for each route - it is assumed that the subnet mask is implicit in - whatever network number is specified in each route entry */ - route.plen = nm_utils_ip4_get_default_prefix (rt_addr); - if (rt_addr & ~nm_utils_ip4_prefix_to_netmask (route.plen)) { - /* RFC 943: target not "this network"; using host routing */ - route.plen = 32; - } - route.gateway = rt_route; - route.source = NM_PLATFORM_SOURCE_DHCP; - route.metric = priv->priority; - - nm_ip4_config_add_route (ip4_config, &route); - nm_log_info (LOGD_DHCP, " static route %s", - nm_platform_ip4_route_to_string (&route)); - } - -out: - g_strfreev (searches); -} - -static void -process_domain_search (const char *str, GFunc add_func, gpointer user_data) -{ - char **searches, **s; - char *unescaped, *p; - int i; - - g_return_if_fail (str != NULL); - g_return_if_fail (add_func != NULL); - - p = unescaped = g_strdup (str); - do { - p = strstr (p, "\\032"); - if (!p) - break; - - /* Clear the escaped space with real spaces */ - for (i = 0; i < 4; i++) - *p++ = ' '; - } while (*p++); - - if (strchr (unescaped, '\\')) { - nm_log_warn (LOGD_DHCP, " invalid domain search: '%s'", unescaped); - goto out; - } - - searches = g_strsplit (unescaped, " ", 0); - for (s = searches; *s; s++) { - if (strlen (*s)) { - nm_log_info (LOGD_DHCP, " domain search '%s'", *s); - add_func (*s, user_data); - } - } - g_strfreev (searches); - -out: - g_free (unescaped); -} - -static void -ip4_add_domain_search (gpointer data, gpointer user_data) -{ - nm_ip4_config_add_search (NM_IP4_CONFIG (user_data), (const char *) data); -} - -/* Given a table of DHCP options from the client, convert into an IP4Config */ -static NMIP4Config * -ip4_options_to_config (NMDHCPClient *self) -{ - NMDHCPClientPrivate *priv; - NMIP4Config *ip4_config = NULL; - guint32 tmp_addr; - NMPlatformIP4Address address; - char *str = NULL; - guint32 gwaddr = 0, plen = 0; - - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + g_return_val_if_fail (reason != NULL, FALSE); priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - g_return_val_if_fail (priv->options != NULL, NULL); - - ip4_config = nm_ip4_config_new (); - memset (&address, 0, sizeof (address)); - address.timestamp = nm_utils_get_monotonic_timestamp_s (); - str = g_hash_table_lookup (priv->options, "new_ip_address"); - if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { - address.address = tmp_addr; - nm_log_info (LOGD_DHCP4, " address %s", str); - } else - goto error; - - str = g_hash_table_lookup (priv->options, "new_subnet_mask"); - if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { - plen = nm_utils_ip4_netmask_to_prefix (tmp_addr); - nm_log_info (LOGD_DHCP4, " plen %d (%s)", plen, str); - } else { - /* Get default netmask for the IP according to appropriate class. */ - plen = nm_utils_ip4_get_default_prefix (address.address); - nm_log_info (LOGD_DHCP4, " plen %d (default)", plen); - } - address.plen = plen; - - /* Routes: if the server returns classless static routes, we MUST ignore - * the 'static_routes' option. - */ - if (!ip4_process_classless_routes (self, priv->options, ip4_config, &gwaddr)) - process_classful_routes (self, priv->options, ip4_config); - - if (gwaddr) { - nm_log_info (LOGD_DHCP4, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL)); - nm_ip4_config_set_gateway (ip4_config, gwaddr); - } else { - /* If the gateway wasn't provided as a classless static route with a - * subnet length of 0, try to find it using the old-style 'routers' option. - */ - str = g_hash_table_lookup (priv->options, "new_routers"); - if (str) { - char **routers = g_strsplit (str, " ", 0); - char **s; - - for (s = routers; *s; s++) { - /* FIXME: how to handle multiple routers? */ - if (inet_pton (AF_INET, *s, &gwaddr) > 0) { - nm_ip4_config_set_gateway (ip4_config, gwaddr); - nm_log_info (LOGD_DHCP4, " gateway %s", *s); - break; - } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid gateway '%s'", *s); - } - g_strfreev (routers); - } - } + if (g_strcmp0 (priv->iface, iface) != 0) + return FALSE; + if (priv->pid != pid) + return FALSE; - /* - * RFC 2132, section 9.7 - * DHCP clients use the contents of the 'server identifier' field - * as the destination address for any DHCP messages unicast to - * the DHCP server. - * - * Some ISP's provide leases from central servers that are on - * different subnets that the address offered. If the host - * does not configure the interface as the default route, the - * dhcp server may not be reachable via unicast, and a host - * specific route is needed. - **/ - str = g_hash_table_lookup (priv->options, "new_dhcp_server_identifier"); - if (str) { - if (inet_pton (AF_INET, str, &tmp_addr) > 0) { - NMPlatformIP4Route route; - guint32 mask = nm_utils_ip4_prefix_to_netmask (address.plen); - - nm_log_info (LOGD_DHCP4, " server identifier %s", str); - if ((tmp_addr & mask) != (address.address & mask)) { - /* DHCP server not on assigned subnet, route needed */ - memset (&route, 0, sizeof (route)); - route.network = tmp_addr; - route.plen = 32; - /* this will be a device route if gwaddr is 0 */ - route.gateway = gwaddr; - route.source = NM_PLATFORM_SOURCE_DHCP; - route.metric = priv->priority; - nm_ip4_config_add_route (ip4_config, &route); - nm_log_dbg (LOGD_IP, "adding route for server identifier: %s", - nm_platform_ip4_route_to_string (&route)); + old_state = priv->state; + new_state = reason_to_state (priv->iface, reason); + nm_log_dbg (LOGD_DHCP, "(%s): DHCP reason '%s' -> state '%s'", + iface, reason, state_to_string (new_state)); + + if (new_state == NM_DHCP_STATE_BOUND) { + /* Copy options */ + str_options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_hash_table_foreach (options, (GHFunc) copy_option, str_options); + + /* Create the IP config */ + g_warn_if_fail (g_hash_table_size (str_options)); + if (g_hash_table_size (str_options)) { + if (priv->ipv6) { + ip_config = (GObject *) nm_dhcp_utils_ip6_config_from_options (priv->iface, + str_options, + priv->priority, + priv->info_only); + } else { + ip_config = (GObject *) nm_dhcp_utils_ip4_config_from_options (priv->iface, + str_options, + priv->priority); } + g_warn_if_fail (ip_config != NULL); } - else - nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str); - } - - str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time"); - if (str) { - address.lifetime = address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime); - } - - address.source = NM_PLATFORM_SOURCE_DHCP; - nm_ip4_config_add_address (ip4_config, &address); - - str = g_hash_table_lookup (priv->options, "new_host_name"); - if (str) - nm_log_info (LOGD_DHCP4, " hostname '%s'", str); - - str = g_hash_table_lookup (priv->options, "new_domain_name_servers"); - if (str) { - char **searches = g_strsplit (str, " ", 0); - char **s; - - for (s = searches; *s; s++) { - if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_nameserver (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " nameserver '%s'", *s); - } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid nameserver '%s'", *s); - } - g_strfreev (searches); - } - - str = g_hash_table_lookup (priv->options, "new_domain_name"); - if (str) { - char **domains = g_strsplit (str, " ", 0); - char **s; - - for (s = domains; *s; s++) { - nm_log_info (LOGD_DHCP4, " domain name '%s'", *s); - nm_ip4_config_add_domain (ip4_config, *s); - } - g_strfreev (domains); - } - - str = g_hash_table_lookup (priv->options, "new_domain_search"); - if (str) - process_domain_search (str, ip4_add_domain_search, ip4_config); - - str = g_hash_table_lookup (priv->options, "new_netbios_name_servers"); - if (str) { - char **searches = g_strsplit (str, " ", 0); - char **s; - - for (s = searches; *s; s++) { - if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_wins (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " wins '%s'", *s); - } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid WINS server '%s'", *s); - } - g_strfreev (searches); - } - - str = g_hash_table_lookup (priv->options, "new_interface_mtu"); - if (str) { - int int_mtu; - - errno = 0; - int_mtu = strtol (str, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) - goto error; - - if (int_mtu > 576) - nm_ip4_config_set_mtu (ip4_config, int_mtu); - } - - str = g_hash_table_lookup (priv->options, "new_nis_domain"); - if (str) { - nm_log_info (LOGD_DHCP4, " NIS domain '%s'", str); - nm_ip4_config_set_nis_domain (ip4_config, str); - } - - str = g_hash_table_lookup (priv->options, "new_nis_servers"); - if (str) { - char **searches = g_strsplit (str, " ", 0); - char **s; - - for (s = searches; *s; s++) { - if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_add_nis_server (ip4_config, tmp_addr); - nm_log_info (LOGD_DHCP4, " nis '%s'", *s); - } else - nm_log_warn (LOGD_DHCP4, "ignoring invalid NIS server '%s'", *s); - } - g_strfreev (searches); - } - - return ip4_config; - -error: - g_object_unref (ip4_config); - return NULL; -} - -NMIP4Config * -nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test) -{ - NMDHCPClientPrivate *priv; - - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); - - priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - - if (test && !state_is_bound (priv->state)) { - nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface); - return NULL; - } - - if (!g_hash_table_size (priv->options)) { - /* We never got a response from the DHCP client */ - return NULL; - } - - return ip4_options_to_config (self); -} - -/********************************************/ - -static void -ip6_add_domain_search (gpointer data, gpointer user_data) -{ - nm_ip6_config_add_search (NM_IP6_CONFIG (user_data), (const char *) data); -} - -/* Given a table of DHCP options from the client, convert into an IP6Config */ -static NMIP6Config * -ip6_options_to_config (NMDHCPClient *self) -{ - NMDHCPClientPrivate *priv; - NMIP6Config *ip6_config = NULL; - struct in6_addr tmp_addr; - NMPlatformIP6Address address; - char *str = NULL; - GHashTableIter iter; - gpointer key, value; - - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); - - memset (&address, 0, sizeof (address)); - address.plen = 128; - address.timestamp = nm_utils_get_monotonic_timestamp_s (); - - priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - g_return_val_if_fail (priv->options != NULL, NULL); - - g_hash_table_iter_init (&iter, priv->options); - while (g_hash_table_iter_next (&iter, &key, &value)) { - nm_log_dbg (LOGD_DHCP6, "(%s): option '%s'=>'%s'", - priv->iface, (const char *) key, (const char *) value); - } - - ip6_config = nm_ip6_config_new (); - - str = g_hash_table_lookup (priv->options, "new_max_life"); - if (str) { - address.lifetime = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " valid_lft %d", address.lifetime); - } - - str = g_hash_table_lookup (priv->options, "new_preferred_life"); - if (str) { - address.preferred = strtoul (str, NULL, 10); - nm_log_info (LOGD_DHCP6, " preferred_lft %d", address.preferred); - } - - str = g_hash_table_lookup (priv->options, "new_ip6_address"); - if (str) { - if (!inet_pton (AF_INET6, str, &tmp_addr)) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCP returned invalid address '%s'", - priv->iface, str); - goto error; - } - - address.address = tmp_addr; - address.source = NM_PLATFORM_SOURCE_DHCP; - nm_ip6_config_add_address (ip6_config, &address); - nm_log_info (LOGD_DHCP6, " address %s", str); - } else if (priv->info_only == FALSE) { - /* No address in Managed mode is a hard error */ - goto error; - } - - str = g_hash_table_lookup (priv->options, "new_host_name"); - if (str) - nm_log_info (LOGD_DHCP6, " hostname '%s'", str); - - str = g_hash_table_lookup (priv->options, "new_dhcp6_name_servers"); - if (str) { - char **searches = g_strsplit (str, " ", 0); - char **s; - - for (s = searches; *s; s++) { - if (inet_pton (AF_INET6, *s, &tmp_addr) > 0) { - nm_ip6_config_add_nameserver (ip6_config, &tmp_addr); - nm_log_info (LOGD_DHCP6, " nameserver '%s'", *s); - } else - nm_log_warn (LOGD_DHCP6, "ignoring invalid nameserver '%s'", *s); - } - g_strfreev (searches); } - str = g_hash_table_lookup (priv->options, "new_dhcp6_domain_search"); - if (str) - process_domain_search (str, ip6_add_domain_search, ip6_config); + nm_dhcp_client_set_state (self, new_state, ip_config, str_options); - return ip6_config; + if (str_options) + g_hash_table_destroy (str_options); + g_clear_object (&ip_config); -error: - g_object_unref (ip6_config); - return NULL; -} - -NMIP6Config * -nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) -{ - NMDHCPClientPrivate *priv; - - g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); - - priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - - if (test && !state_is_bound (priv->state)) { - nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface); - return NULL; - } - - if (!g_hash_table_size (priv->options)) { - /* We never got a response from the DHCP client */ - return NULL; - } - - return ip6_options_to_config (self); + return TRUE; } /********************************************/ static void -nm_dhcp_client_init (NMDHCPClient *self) +nm_dhcp_client_init (NMDhcpClient *self) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); - - priv->options = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - priv->pid = -1; + NM_DHCP_CLIENT_GET_PRIVATE (self)->pid = -1; } static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (object); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (object); switch (prop_id) { case PROP_IFACE: g_value_set_string (value, priv->iface); break; + case PROP_IFINDEX: + g_value_set_int (value, priv->ifindex); + break; case PROP_HWADDR: g_value_set_boxed (value, priv->hwaddr); break; @@ -1528,13 +826,18 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (object); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (object); switch (prop_id) { case PROP_IFACE: /* construct-only */ priv->iface = g_strdup (g_value_get_string (value)); break; + case PROP_IFINDEX: + /* construct-only */ + priv->ifindex = g_value_get_int (value); + g_warn_if_fail (priv->ifindex > 0); + break; case PROP_HWADDR: /* construct only */ priv->hwaddr = g_value_dup_boxed (value); @@ -1563,23 +866,17 @@ set_property (GObject *object, guint prop_id, static void dispose (GObject *object) { - NMDHCPClient *self = NM_DHCP_CLIENT (object); - NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); + NMDhcpClient *self = NM_DHCP_CLIENT (object); + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); /* Stopping the client is left up to the controlling device * explicitly since we may want to quit NetworkManager but not terminate * the DHCP client. */ - if (priv->remove_id) { - g_source_remove (priv->remove_id); - priv->remove_id = 0; - } + watch_cleanup (self); + timeout_cleanup (self); - if (priv->options) { - g_hash_table_destroy (priv->options); - priv->options = NULL; - } g_clear_pointer (&priv->iface, g_free); if (priv->hwaddr) { @@ -1596,11 +893,11 @@ dispose (GObject *object) } static void -nm_dhcp_client_class_init (NMDHCPClientClass *client_class) +nm_dhcp_client_class_init (NMDhcpClientClass *client_class) { GObjectClass *object_class = G_OBJECT_CLASS (client_class); - g_type_class_add_private (client_class, sizeof (NMDHCPClientPrivate)); + g_type_class_add_private (client_class, sizeof (NMDhcpClientPrivate)); /* virtual methods */ object_class->dispose = dispose; @@ -1612,78 +909,59 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) g_object_class_install_property (object_class, PROP_IFACE, - g_param_spec_string (NM_DHCP_CLIENT_INTERFACE, - "iface", - "Interface", + g_param_spec_string (NM_DHCP_CLIENT_INTERFACE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IFINDEX, + g_param_spec_int (NM_DHCP_CLIENT_IFINDEX, "", "", + -1, G_MAXINT, -1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_HWADDR, - g_param_spec_boxed (NM_DHCP_CLIENT_HWADDR, - "hwaddr", - "hardware address", + g_param_spec_boxed (NM_DHCP_CLIENT_HWADDR, "", "", G_TYPE_BYTE_ARRAY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_IPV6, - g_param_spec_boolean (NM_DHCP_CLIENT_IPV6, - "ipv6", - "IPv6", + g_param_spec_boolean (NM_DHCP_CLIENT_IPV6, "", "", FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_UUID, - g_param_spec_string (NM_DHCP_CLIENT_UUID, - "uuid", - "UUID", + g_param_spec_string (NM_DHCP_CLIENT_UUID, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PRIORITY, - g_param_spec_uint (NM_DHCP_CLIENT_PRIORITY, - "priority", - "Priority", - 0, G_MAXUINT, 0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_uint (NM_DHCP_CLIENT_PRIORITY, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_TIMEOUT, - g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, - "timeout", - "Timeout", + g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, "", "", 0, G_MAXUINT, 45, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[SIGNAL_STATE_CHANGED] = g_signal_new (NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDHCPClientClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - signals[SIGNAL_TIMEOUT] = - g_signal_new (NM_DHCP_CLIENT_SIGNAL_TIMEOUT, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDHCPClientClass, timeout), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SIGNAL_REMOVE] = - g_signal_new (NM_DHCP_CLIENT_SIGNAL_REMOVE, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDHCPClientClass, remove), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + G_STRUCT_OFFSET (NMDhcpClientClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_OBJECT, G_TYPE_HASH_TABLE); } diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index ad18926a..971c9dc0 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -16,8 +16,8 @@ * Copyright (C) 2005 - 2010 Red Hat, Inc. */ -#ifndef NM_DHCP_CLIENT_H -#define NM_DHCP_CLIENT_H +#ifndef __NETWORKMANAGER_DHCP_CLIENT_H__ +#define __NETWORKMANAGER_DHCP_CLIENT_H__ #include #include @@ -28,130 +28,142 @@ #include #define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ()) -#define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDHCPClient)) -#define NM_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CLIENT, NMDHCPClientClass)) +#define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClient)) +#define NM_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) #define NM_IS_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_CLIENT)) #define NM_IS_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_CLIENT)) -#define NM_DHCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_CLIENT, NMDHCPClientClass)) +#define NM_DHCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) #define NM_DHCP_CLIENT_INTERFACE "iface" +#define NM_DHCP_CLIENT_IFINDEX "ifindex" #define NM_DHCP_CLIENT_HWADDR "hwaddr" #define NM_DHCP_CLIENT_IPV6 "ipv6" #define NM_DHCP_CLIENT_UUID "uuid" #define NM_DHCP_CLIENT_PRIORITY "priority" #define NM_DHCP_CLIENT_TIMEOUT "timeout" -#define NM_DHCP_CLIENT_SIGNAL_TIMEOUT "timeout" #define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" -#define NM_DHCP_CLIENT_SIGNAL_REMOVE "remove" typedef enum { - DHC_NBI = 0, /* no broadcast interfaces found */ - DHC_PREINIT, /* configuration started */ - DHC_PREINIT6, /* configuration started */ - DHC_BOUND4, /* IPv4 lease obtained */ - DHC_BOUND6, /* IPv6 lease obtained */ - DHC_IPV4LL, /* IPv4LL address obtained */ - DHC_RENEW4, /* IPv4 lease renewed */ - DHC_RENEW6, /* IPv6 lease renewed */ - DHC_REBOOT, /* have valid lease, but now obtained a different one */ - DHC_REBIND4, /* IPv4 new/different lease */ - DHC_REBIND6, /* IPv6 new/different lease */ - DHC_DEPREF6, /* IPv6 lease depreferred */ - DHC_STOP, /* remove old lease */ - DHC_STOP6, /* remove old lease */ - DHC_MEDIUM, /* media selection begun */ - DHC_TIMEOUT, /* timed out contacting DHCP server */ - DHC_FAIL, /* all attempts to contact server timed out, sleeping */ - DHC_EXPIRE, /* lease has expired, renewing */ - DHC_EXPIRE6, /* lease has expired, renewing */ - DHC_RELEASE, /* releasing lease */ - DHC_RELEASE6, /* releasing lease */ - DHC_START, /* sent when dhclient started OK */ - DHC_ABEND, /* dhclient exited abnormally */ - DHC_END, /* dhclient exited normally */ - DHC_END_OPTIONS, /* last option in subscription sent */ -} NMDHCPState; + NM_DHCP_STATE_UNKNOWN = 0, + NM_DHCP_STATE_BOUND, /* new lease or lease changed */ + NM_DHCP_STATE_TIMEOUT, /* timed out contacting server */ + NM_DHCP_STATE_DONE, /* client quit or stopped */ + NM_DHCP_STATE_EXPIRE, /* lease expired or NAKed */ + NM_DHCP_STATE_FAIL, /* failed for some reason */ + __NM_DHCP_STATE_MAX, + NM_DHCP_STATE_MAX = __NM_DHCP_STATE_MAX - 1, +} NMDhcpState; typedef struct { GObject parent; -} NMDHCPClient; +} NMDhcpClient; typedef struct { GObjectClass parent; /* Methods */ - GPid (*ip4_start) (NMDHCPClient *self, - const char *dhcp_client_id, - GByteArray *anycast_addr, - const char *hostname); + gboolean (*ip4_start) (NMDhcpClient *self, + const char *anycast_addr, + const char *last_ip4_address); - GPid (*ip6_start) (NMDHCPClient *self, - GByteArray *anycast_addr, - const char *hostname, - gboolean info_only, - const GByteArray *duid); + gboolean (*ip6_start) (NMDhcpClient *self, + const char *anycast_addr, + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy, + const GByteArray *duid); - void (*stop) (NMDHCPClient *self, - gboolean release, - const GByteArray *duid); + void (*stop) (NMDhcpClient *self, + gboolean release, + const GByteArray *duid); /** * get_duid: - * @self: the #NMDHCPClient + * @self: the #NMDhcpClient * * Attempts to find an existing DHCPv6 DUID for this client in the DHCP * client's persistent configuration. Returned DUID should be the binary * representation of the DUID. If no DUID is found, %NULL should be * returned. */ - GByteArray * (*get_duid) (NMDHCPClient *self); + GByteArray * (*get_duid) (NMDhcpClient *self); /* Signals */ - void (*state_changed) (NMDHCPClient *self, NMDHCPState state); - void (*timeout) (NMDHCPClient *self); - void (*remove) (NMDHCPClient *self); -} NMDHCPClientClass; + void (*state_changed) (NMDhcpClient *self, + NMDhcpState state, + GObject *ip_config, + GHashTable *options); +} NMDhcpClientClass; GType nm_dhcp_client_get_type (void); -GPid nm_dhcp_client_get_pid (NMDHCPClient *self); +typedef const char *(*NMDhcpClientGetPathFunc) (void); -const char *nm_dhcp_client_get_iface (NMDHCPClient *self); +typedef GSList * (*NMDhcpClientGetLeaseConfigsFunc) (const char *iface, + const char *uuid, + gboolean ipv6, + guint32 default_route_metric); -gboolean nm_dhcp_client_get_ipv6 (NMDHCPClient *self); +void _nm_dhcp_client_register (GType gtype, + const char *name, + NMDhcpClientGetPathFunc get_path_func, + NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func); -const char *nm_dhcp_client_get_uuid (NMDHCPClient *self); +pid_t nm_dhcp_client_get_pid (NMDhcpClient *self); -gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self, +const char *nm_dhcp_client_get_iface (NMDhcpClient *self); + +int nm_dhcp_client_get_ifindex (NMDhcpClient *self); + +gboolean nm_dhcp_client_get_ipv6 (NMDhcpClient *self); + +const char *nm_dhcp_client_get_uuid (NMDhcpClient *self); + +const GByteArray *nm_dhcp_client_get_duid (NMDhcpClient *self); + +const GByteArray *nm_dhcp_client_get_hw_addr (NMDhcpClient *self); + +guint32 nm_dhcp_client_get_priority (NMDhcpClient *self); + +GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self); + +const char *nm_dhcp_client_get_hostname (NMDhcpClient *self); + +gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, const char *dhcp_client_id, - GByteArray *dhcp_anycast_addr, - const char *hostname); + const char *dhcp_anycast_addr, + const char *hostname, + const char *last_ip4_address); -gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, - GByteArray *dhcp_anycast_addr, +gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, + const char *dhcp_anycast_addr, const char *hostname, - gboolean info_only); + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy); -void nm_dhcp_client_stop (NMDHCPClient *self, gboolean release); +void nm_dhcp_client_stop (NMDhcpClient *self, gboolean release); -void nm_dhcp_client_new_options (NMDHCPClient *self, - GHashTable *options, - const char *reason); +/* Backend helpers for subclasses */ +void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); -gboolean nm_dhcp_client_foreach_option (NMDHCPClient *self, - GHFunc func, - gpointer user_data); +void nm_dhcp_client_stop_pid (pid_t pid, const char *iface); -NMIP4Config *nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test); +void nm_dhcp_client_watch_child (NMDhcpClient *self, pid_t pid); -NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test); +void nm_dhcp_client_set_state (NMDhcpClient *self, + NMDhcpState new_state, + GObject *ip_config, /* NMIP4Config or NMIP6Config */ + GHashTable *options); /* str:str hash */ -/* Backend helpers */ -void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); +gboolean nm_dhcp_client_handle_event (gpointer unused, + const char *iface, + gint pid, + GHashTable *options, + const char *reason, + NMDhcpClient *self); -void nm_dhcp_client_stop_pid (GPid pid, const char *iface); +void nm_dhcp_client_set_client_id (NMDhcpClient *self, GBytes *client_id); -#endif /* NM_DHCP_CLIENT_H */ +#endif /* __NETWORKMANAGER_DHCP_CLIENT_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index 8527e6c0..46e8e0b8 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -17,21 +17,24 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#include +#include "config.h" #include #include #include #include +#include #include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-utils.h" #include "nm-ip4-config.h" #include "nm-utils.h" +#include "nm-platform.h" #include "NetworkManagerUtils.h" +#include "gsystem-local-alloc.h" +#include "nm-utils-internal.h" #define CLIENTID_TAG "send dhcp-client-identifier" -#define CLIENTID_FORMAT CLIENTID_TAG " \"%s\"; # added by NetworkManager" -#define CLIENTID_FORMAT_OCTETS CLIENTID_TAG " %s; # added by NetworkManager" #define HOSTNAME4_TAG "send host-name" #define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager" @@ -71,32 +74,39 @@ add_hostname (GString *str, const char *format, const char *hostname) } static void -add_ip4_config (GString *str, const char *dhcp_client_id, const char *hostname) +add_ip4_config (GString *str, GBytes *client_id, const char *hostname) { - if (dhcp_client_id) { - gboolean is_octets = TRUE; - int i = 0; + if (client_id) { + const char *p; + gsize l; + guint i; - while (dhcp_client_id[i]) { - if ((i % 3) != 2 && !g_ascii_isxdigit (dhcp_client_id[i])) { - is_octets = FALSE; - break; - } - if ((i % 3) == 2 && dhcp_client_id[i] != ':') { - is_octets = FALSE; + p = g_bytes_get_data (client_id, &l); + g_assert (p); + + /* Allow type 0 (non-hardware address) to be represented as a string + * as long as all the characters are printable. + */ + for (i = 1; (p[0] == 0) && i < l; i++) { + if (!g_ascii_isprint (p[i])) break; - } - i++; } - /* If the client ID is just hex digits and : then don't use quotes, - * because dhclient expects either a quoted ASCII string, or a byte - * array formated as hex octets separated by : - */ - if (is_octets) - g_string_append_printf (str, CLIENTID_FORMAT_OCTETS "\n", dhcp_client_id); - else - g_string_append_printf (str, CLIENTID_FORMAT "\n", dhcp_client_id); + g_string_append (str, CLIENTID_TAG " "); + if (i < l) { + /* Unprintable; convert to a hex string */ + for (i = 0; i < l; i++) { + if (i > 0) + g_string_append_c (str, ':'); + g_string_append_printf (str, "%02x", (guint8) p[i]); + } + } else { + /* Printable; just add to the line minus the 'type' */ + g_string_append_c (str, '"'); + g_string_append_len (str, p + 1, l - 1); + g_string_append_c (str, '"'); + } + g_string_append (str, "; # added by NetworkManager\n"); } add_hostname (str, HOSTNAME4_FORMAT "\n", hostname); @@ -124,19 +134,74 @@ add_ip6_config (GString *str, const char *hostname) "send fqdn.server-update on;\n"); } +static GBytes * +read_client_id (const char *str) +{ + gs_free char *s = NULL; + char *p; + + g_assert (!strncmp (str, CLIENTID_TAG, STRLEN (CLIENTID_TAG))); + + str += STRLEN (CLIENTID_TAG); + while (g_ascii_isspace (*str)) + str++; + + if (*str == '"') { + s = g_strdup (str + 1); + p = strrchr (s, '"'); + if (p) + *p = '\0'; + else + return NULL; + } else + s = g_strdup (str); + + g_strchomp (s); + if (s[strlen (s) - 1] == ';') + s[strlen (s) - 1] = '\0'; + + return nm_dhcp_utils_client_id_string_to_bytes (s); +} + +GBytes * +nm_dhcp_dhclient_get_client_id_from_config_file (const char *path) +{ + gs_free char *contents = NULL; + gs_strfreev char **lines = NULL; + char **line; + + g_return_val_if_fail (path != NULL, NULL); + + if (!g_file_test (path, G_FILE_TEST_EXISTS)) + return NULL; + + if (!g_file_get_contents (path, &contents, NULL, NULL)) + return NULL; + + lines = g_strsplit_set (contents, "\n\r", 0); + for (line = lines; lines && *line; line++) { + if (!strncmp (*line, CLIENTID_TAG, STRLEN (CLIENTID_TAG))) + return read_client_id (*line); + } + return NULL; +} + char * nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, - const char *dhcp_client_id, - GByteArray *anycast_addr, + GBytes *client_id, + const char *anycast_addr, const char *hostname, const char *orig_path, - const char *orig_contents) + const char *orig_contents, + GBytes **out_new_client_id) { GString *new_contents; GPtrArray *alsoreq; int i; + g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL); + new_contents = g_string_new (_("# Created by NetworkManager\n")); alsoreq = g_ptr_array_sized_new (5); @@ -153,11 +218,15 @@ nm_dhcp_dhclient_create_config (const char *interface, if (!strlen (g_strstrip (p))) continue; - /* Override config file "dhcp-client-id" and use one from the - * connection. - */ - if (dhcp_client_id && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) - continue; + if (!strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) { + /* Override config file "dhcp-client-id" and use one from the connection */ + if (client_id) + continue; + + /* Otherwise capture and return the existing client id */ + if (out_new_client_id) + *out_new_client_id = read_client_id (p); + } /* Override config file hostname and use one from the connection */ if (hostname) { @@ -225,9 +294,8 @@ nm_dhcp_dhclient_create_config (const char *interface, add_also_request (alsoreq, "dhcp6.name-servers"); add_also_request (alsoreq, "dhcp6.domain-search"); add_also_request (alsoreq, "dhcp6.client-id"); - add_also_request (alsoreq, "dhcp6.server-id"); } else { - add_ip4_config (new_contents, dhcp_client_id, hostname); + add_ip4_config (new_contents, client_id, hostname); add_also_request (alsoreq, "rfc3442-classless-static-routes"); add_also_request (alsoreq, "ms-classless-static-routes"); add_also_request (alsoreq, "static-routes"); @@ -246,22 +314,14 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_c (new_contents, '\n'); - if (anycast_addr && anycast_addr->len == 6) { - const guint8 *p_anycast_addr = anycast_addr->data; - + if (anycast_addr) { g_string_append_printf (new_contents, "interface \"%s\" {\n" " initial-interval 1; \n" - " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" + " anycast-mac ethernet %s;\n" "}\n", - interface, - p_anycast_addr[0], p_anycast_addr[1], - p_anycast_addr[2], p_anycast_addr[3], - p_anycast_addr[4], p_anycast_addr[5]); + interface, anycast_addr); } - /* Finally, assert that anycast_addr was unset or a 48 bit mac address. */ - g_return_val_if_fail (!anycast_addr || anycast_addr->len == 6, g_string_free (new_contents, FALSE)); - return g_string_free (new_contents, FALSE); } @@ -629,7 +689,7 @@ nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, address.timestamp = now_monotonic_ts; address.lifetime = address.preferred = expiry; - address.source = NM_PLATFORM_SOURCE_DHCP; + address.source = NM_IP_CONFIG_SOURCE_DHCP; ip4 = nm_ip4_config_new (); nm_ip4_config_add_address (ip4, &address); diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.h b/src/dhcp-manager/nm-dhcp-dhclient-utils.h index e8d91b31..a1828add 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.h +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.h @@ -16,8 +16,8 @@ * Copyright (C) 2010 Red Hat, Inc. */ -#ifndef NM_DHCP_DHCLIENT_UTILS_H -#define NM_DHCP_DHCLIENT_UTILS_H +#ifndef __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ +#define __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ #include #include @@ -27,11 +27,12 @@ char *nm_dhcp_dhclient_create_config (const char *interface, gboolean is_ip6, - const char *dhcp_client_id, - GByteArray *anycast_addr, + GBytes *client_id, + const char *anycast_addr, const char *hostname, const char *orig_path, - const char *orig_contents); + const char *orig_contents, + GBytes **out_new_client_id); char *nm_dhcp_dhclient_escape_duid (const GByteArray *duid); @@ -48,5 +49,7 @@ GSList *nm_dhcp_dhclient_read_lease_ip_configs (const char *iface, gboolean ipv6, GDateTime *now); -#endif /* NM_DHCP_DHCLIENT_UTILS_H */ +GBytes *nm_dhcp_dhclient_get_client_id_from_config_file (const char *path); + +#endif /* __NETWORKMANAGER_DHCP_DHCLIENT_UTILS_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index 4232ee0c..504e8d5d 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -18,6 +18,8 @@ * Copyright (C) 2005 - 2012 Red Hat, Inc. */ +#include "config.h" + #define _XOPEN_SOURCE #include #undef _XOPEN_SOURCE @@ -34,49 +36,35 @@ #include #include -#include - #include "nm-dhcp-dhclient.h" #include "nm-utils.h" #include "nm-logging.h" #include "nm-dhcp-dhclient-utils.h" #include "nm-dhcp-manager.h" #include "nm-posix-signals.h" +#include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" +#include "gsystem-local-alloc.h" -G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) +G_DEFINE_TYPE (NMDhcpDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) -#define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientPrivate)) +#define NM_DHCP_DHCLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientPrivate)) typedef struct { - const char *path; char *conf_file; const char *def_leasefile; char *lease_file; char *pid_file; -} NMDHCPDhclientPrivate; +} NMDhcpDhclientPrivate; -const char * -nm_dhcp_dhclient_get_path (const char *try_first) +static const char * +nm_dhcp_dhclient_get_path (void) { - static const char *dhclient_paths[] = { - "/sbin/dhclient", - "/usr/sbin/dhclient", - "/usr/pkg/sbin/dhclient", - "/usr/local/sbin/dhclient", - NULL - }; - const char **path = dhclient_paths; - - if (strlen (try_first) && g_file_test (try_first, G_FILE_TEST_EXISTS)) - return try_first; - - while (*path != NULL) { - if (g_file_test (*path, G_FILE_TEST_EXISTS)) - break; - path++; - } + const char *path = NULL; - return *path; + if (WITH_DHCLIENT) + path = nm_utils_find_helper ("dhclient", DHCLIENT_PATH, NULL); + return path; } /** @@ -136,10 +124,11 @@ get_dhclient_leasefile (const char *iface, return NULL; } -GSList * +static GSList * nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, const char *uuid, - gboolean ipv6) + gboolean ipv6, + guint32 default_route_metric) { char *contents = NULL; char *leasefile; @@ -165,10 +154,11 @@ static gboolean merge_dhclient_config (const char *iface, const char *conf_file, gboolean is_ip6, - const char *dhcp_client_id, - GByteArray *anycast_addr, + GBytes *client_id, + const char *anycast_addr, const char *hostname, const char *orig_path, + GBytes **out_new_client_id, GError **error) { char *orig = NULL, *new; @@ -187,7 +177,7 @@ merge_dhclient_config (const char *iface, } } - new = nm_dhcp_dhclient_create_config (iface, is_ip6, dhcp_client_id, anycast_addr, hostname, orig_path, orig); + new = nm_dhcp_dhclient_create_config (iface, is_ip6, client_id, anycast_addr, hostname, orig_path, orig, out_new_client_id); g_assert (new); success = g_file_set_contents (conf_file, new, -1, error); g_free (new); @@ -271,9 +261,10 @@ static char * create_dhclient_config (const char *iface, gboolean is_ip6, const char *uuid, - const char *dhcp_client_id, - GByteArray *dhcp_anycast_addr, - const char *hostname) + GBytes *client_id, + const char *dhcp_anycast_addr, + const char *hostname, + GBytes **out_new_client_id) { char *orig = NULL, *new = NULL; GError *error = NULL; @@ -298,7 +289,7 @@ create_dhclient_config (const char *iface, } error = NULL; - success = merge_dhclient_config (iface, new, is_ip6, dhcp_client_id, dhcp_anycast_addr, hostname, orig, &error); + success = merge_dhclient_config (iface, new, is_ip6, client_id, dhcp_anycast_addr, hostname, orig, out_new_client_id, &error); if (!success) { nm_log_warn (LOGD_DHCP, "(%s): error creating dhclient%s configuration: %s", iface, is_ip6 ? "6" : "", error->message); @@ -324,23 +315,24 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED) nm_unblock_posix_signals (NULL); } -static GPid -dhclient_start (NMDHCPClient *client, +static gboolean +dhclient_start (NMDhcpClient *client, const char *mode_opt, const GByteArray *duid, - gboolean release) + gboolean release, + pid_t *out_pid) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GPtrArray *argv = NULL; - GPid pid = -1; + pid_t pid; GError *error = NULL; - const char *iface, *uuid, *system_bus_address; + const char *iface, *uuid, *system_bus_address, *dhclient_path = NULL; char *binary_name, *cmd_str, *pid_file = NULL, *system_bus_address_env = NULL; gboolean ipv6, success; guint log_domain; char *escaped, *preferred_leasefile_path = NULL; - g_return_val_if_fail (priv->pid_file == NULL, -1); + g_return_val_if_fail (priv->pid_file == NULL, FALSE); iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); @@ -348,9 +340,10 @@ dhclient_start (NMDHCPClient *client, log_domain = ipv6 ? LOGD_DHCP6 : LOGD_DHCP4; - if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { - nm_log_warn (log_domain, "%s does not exist.", priv->path); - return -1; + dhclient_path = nm_dhcp_dhclient_get_path (); + if (!dhclient_path) { + nm_log_warn (log_domain, "dhclient could not be found"); + return FALSE; } pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", @@ -358,7 +351,7 @@ dhclient_start (NMDHCPClient *client, iface); /* Kill any existing dhclient from the pidfile */ - binary_name = g_path_get_basename (priv->path); + binary_name = g_path_get_basename (dhclient_path); nm_dhcp_client_stop_existing (pid_file, binary_name); g_free (binary_name); @@ -404,15 +397,21 @@ dhclient_start (NMDHCPClient *client, iface, priv->lease_file, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); - return -1; + g_free (pid_file); + return FALSE; } } argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) priv->path); + g_ptr_array_add (argv, (gpointer) dhclient_path); g_ptr_array_add (argv, (gpointer) "-d"); + /* Be quiet. dhclient logs to syslog anyway. And we duplicate the syslog + * to stderr in case of NM running with --debug. + */ + g_ptr_array_add (argv, (gpointer) "-q"); + if (release) g_ptr_array_add (argv, (gpointer) "-r"); @@ -456,68 +455,80 @@ dhclient_start (NMDHCPClient *client, nm_log_dbg (log_domain, "running: %s", cmd_str); g_free (cmd_str); - if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, - &dhclient_child_setup, NULL, &pid, &error)) { - nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message); - g_error_free (error); - pid = -1; - } else { + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + &dhclient_child_setup, NULL, &pid, &error)) { + g_assert (pid > 0); nm_log_info (log_domain, "dhclient started with pid %d", pid); + if (release == FALSE) + nm_dhcp_client_watch_child (client, pid); priv->pid_file = pid_file; + } else { + nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message); + g_error_free (error); + g_free (pid_file); } + if (out_pid) + *out_pid = pid; + g_ptr_array_free (argv, TRUE); g_free (system_bus_address_env); - return pid; + return pid > 0 ? TRUE : FALSE; } -static GPid -ip4_start (NMDHCPClient *client, - const char *dhcp_client_id, - GByteArray *dhcp_anycast_addr, - const char *hostname) +static gboolean +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface, *uuid; + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + GBytes *client_id; + gs_unref_bytes GBytes *new_client_id = NULL; + const char *iface, *uuid, *hostname; + gboolean success = FALSE; iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); + client_id = nm_dhcp_client_get_client_id (client); + hostname = nm_dhcp_client_get_hostname (client); - priv->conf_file = create_dhclient_config (iface, FALSE, uuid, dhcp_client_id, dhcp_anycast_addr, hostname); - if (!priv->conf_file) { + priv->conf_file = create_dhclient_config (iface, FALSE, uuid, client_id, dhcp_anycast_addr, hostname, &new_client_id); + if (priv->conf_file) { + if (new_client_id) + nm_dhcp_client_set_client_id (client, new_client_id); + success = dhclient_start (client, NULL, NULL, FALSE, NULL); + } else nm_log_warn (LOGD_DHCP4, "(%s): error creating dhclient configuration file.", iface); - return -1; - } - return dhclient_start (client, NULL, NULL, FALSE); + return success; } -static GPid -ip6_start (NMDHCPClient *client, - GByteArray *dhcp_anycast_addr, - const char *hostname, +static gboolean +ip6_start (NMDhcpClient *client, + const char *dhcp_anycast_addr, gboolean info_only, + NMSettingIP6ConfigPrivacy privacy, const GByteArray *duid) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); - const char *iface, *uuid; + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + const char *iface, *uuid, *hostname; iface = nm_dhcp_client_get_iface (client); uuid = nm_dhcp_client_get_uuid (client); + hostname = nm_dhcp_client_get_hostname (client); - priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname); + priv->conf_file = create_dhclient_config (iface, TRUE, uuid, NULL, dhcp_anycast_addr, hostname, NULL); if (!priv->conf_file) { nm_log_warn (LOGD_DHCP6, "(%s): error creating dhclient6 configuration file.", iface); - return -1; + return FALSE; } - return dhclient_start (client, info_only ? "-S" : "-N", duid, FALSE); + return dhclient_start (client, info_only ? "-S" : "-N", duid, FALSE, NULL); } static void -stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); /* Chain up to parent */ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release, duid); @@ -533,20 +544,37 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) } if (release) { - GPid rpid; + pid_t rpid = -1; - rpid = dhclient_start (client, NULL, duid, TRUE); - if (rpid > 0) { + if (dhclient_start (client, NULL, duid, TRUE, &rpid)) { /* Wait a few seconds for the release to happen */ nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client)); } } } +static void +state_changed (NMDhcpClient *client, + NMDhcpState state, + GObject *ip_config, + GHashTable *options) +{ + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + gs_unref_bytes GBytes *client_id = NULL; + + if (nm_dhcp_client_get_client_id (client)) + return; + if (state != NM_DHCP_STATE_BOUND) + return; + + client_id = nm_dhcp_dhclient_get_client_id_from_config_file (priv->conf_file); + nm_dhcp_client_set_client_id (client, client_id); +} + static GByteArray * -get_duid (NMDHCPClient *client) +get_duid (NMDhcpClient *client) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GByteArray *duid = NULL; char *leasefile; GError *error = NULL; @@ -595,13 +623,11 @@ static const char *def_leasefiles[] = { }; static void -nm_dhcp_dhclient_init (NMDHCPDhclient *self) +nm_dhcp_dhclient_init (NMDhcpDhclient *self) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); const char **iter = &def_leasefiles[0]; - priv->path = nm_dhcp_dhclient_get_path (DHCLIENT_PATH); - while (iter && *iter) { if (g_file_test (*iter, G_FILE_TEST_EXISTS)) { priv->def_leasefile = *iter; @@ -613,12 +639,21 @@ nm_dhcp_dhclient_init (NMDHCPDhclient *self) /* Fallback option */ if (!priv->def_leasefile) priv->def_leasefile = SYSCONFDIR "/dhclient6.leases"; + + g_signal_connect (nm_dhcp_listener_get (), + NM_DHCP_LISTENER_EVENT, + G_CALLBACK (nm_dhcp_client_handle_event), + self); } static void dispose (GObject *object) { - NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (object); + NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (object); + + g_signal_handlers_disconnect_by_func (nm_dhcp_listener_get (), + G_CALLBACK (nm_dhcp_client_handle_event), + NM_DHCP_DHCLIENT (object)); g_free (priv->pid_file); g_free (priv->conf_file); @@ -628,12 +663,12 @@ dispose (GObject *object) } static void -nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class) +nm_dhcp_dhclient_class_init (NMDhcpDhclientClass *dhclient_class) { - NMDHCPClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhclient_class); + NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhclient_class); GObjectClass *object_class = G_OBJECT_CLASS (dhclient_class); - g_type_class_add_private (dhclient_class, sizeof (NMDHCPDhclientPrivate)); + g_type_class_add_private (dhclient_class, sizeof (NMDhcpDhclientPrivate)); /* virtual methods */ object_class->dispose = dispose; @@ -642,5 +677,16 @@ nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class) client_class->ip6_start = ip6_start; client_class->stop = stop; client_class->get_duid = get_duid; + client_class->state_changed = state_changed; +} + +static void __attribute__((constructor)) +register_dhcp_dhclient (void) +{ + g_type_init (); + _nm_dhcp_client_register (NM_TYPE_DHCP_DHCLIENT, + "dhclient", + nm_dhcp_dhclient_get_path, + nm_dhcp_dhclient_get_lease_ip_configs); } diff --git a/src/dhcp-manager/nm-dhcp-dhclient.h b/src/dhcp-manager/nm-dhcp-dhclient.h index 20219a63..5abcc08e 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.h +++ b/src/dhcp-manager/nm-dhcp-dhclient.h @@ -16,8 +16,8 @@ * Copyright (C) 2005 - 2010 Red Hat, Inc. */ -#ifndef NM_DHCP_DHCLIENT_H -#define NM_DHCP_DHCLIENT_H +#ifndef __NETWORKMANAGER_DHCP_DHCLIENT_H__ +#define __NETWORKMANAGER_DHCP_DHCLIENT_H__ #include #include @@ -25,27 +25,21 @@ #include "nm-dhcp-client.h" #define NM_TYPE_DHCP_DHCLIENT (nm_dhcp_dhclient_get_type ()) -#define NM_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclient)) -#define NM_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientClass)) +#define NM_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclient)) +#define NM_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) #define NM_IS_DHCP_DHCLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCLIENT)) #define NM_IS_DHCP_DHCLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCLIENT)) -#define NM_DHCP_DHCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCLIENT, NMDHCPDhclientClass)) +#define NM_DHCP_DHCLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCLIENT, NMDhcpDhclientClass)) typedef struct { - NMDHCPClient parent; -} NMDHCPDhclient; + NMDhcpClient parent; +} NMDhcpDhclient; typedef struct { - NMDHCPClientClass parent; -} NMDHCPDhclientClass; + NMDhcpClientClass parent; +} NMDhcpDhclientClass; GType nm_dhcp_dhclient_get_type (void); -GSList *nm_dhcp_dhclient_get_lease_ip_configs (const char *iface, - const char *uuid, - gboolean ipv6); - -const char *nm_dhcp_dhclient_get_path (const char *try_first); - -#endif /* NM_DHCP_DHCLIENT_H */ +#endif /* __NETWORKMANAGER_DHCP_DHCLIENT_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index acfbee26..e5a40c2f 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -21,10 +21,10 @@ */ -#include +#include "config.h" + #include #include -#include #include #include #include @@ -38,38 +38,25 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-posix-signals.h" +#include "NetworkManagerUtils.h" +#include "nm-dhcp-listener.h" -G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT) +G_DEFINE_TYPE (NMDhcpDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT) -#define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdPrivate)) +#define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdPrivate)) typedef struct { - const char *path; char *pid_file; -} NMDHCPDhcpcdPrivate; +} NMDhcpDhcpcdPrivate; -const char * -nm_dhcp_dhcpcd_get_path (const char *try_first) +static const char * +nm_dhcp_dhcpcd_get_path (void) { - static const char *dhcpcd_paths[] = { - "/sbin/dhcpcd", - "/usr/sbin/dhcpcd", - "/usr/pkg/sbin/dhcpcd", - "/usr/local/sbin/dhcpcd", - NULL - }; - const char **path = dhcpcd_paths; - - if (strlen (try_first) && g_file_test (try_first, G_FILE_TEST_EXISTS)) - return try_first; - - while (*path != NULL) { - if (g_file_test (*path, G_FILE_TEST_EXISTS)) - break; - path++; - } + const char *path = NULL; - return *path; + if (WITH_DHCPCD) + path = nm_utils_find_helper ("dhcpcd", DHCPCD_PATH, NULL); + return path; } static void @@ -86,20 +73,17 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED) nm_unblock_posix_signals (NULL); } -static GPid -ip4_start (NMDHCPClient *client, - const char *dhcp_client_id, - GByteArray *dhcp_anycast_addr, - const char *hostname) +static gboolean +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { - NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); + NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); GPtrArray *argv = NULL; - GPid pid = -1; + pid_t pid = -1; GError *error = NULL; char *pid_contents = NULL, *binary_name, *cmd_str; - const char *iface; + const char *iface, *dhcpcd_path, *hostname; - g_return_val_if_fail (priv->pid_file == NULL, -1); + g_return_val_if_fail (priv->pid_file == NULL, FALSE); iface = nm_dhcp_client_get_iface (client); @@ -108,18 +92,19 @@ ip4_start (NMDHCPClient *client, */ priv->pid_file = g_strdup_printf (RUNDIR "/dhcpcd-%s.pid", iface); - if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { - nm_log_warn (LOGD_DHCP4, "%s does not exist.", priv->path); - return -1; + dhcpcd_path = nm_dhcp_dhcpcd_get_path (); + if (!dhcpcd_path) { + nm_log_warn (LOGD_DHCP4, "dhcpcd could not be found"); + return FALSE; } /* Kill any existing dhcpcd from the pidfile */ - binary_name = g_path_get_basename (priv->path); + binary_name = g_path_get_basename (dhcpcd_path); nm_dhcp_client_stop_existing (priv->pid_file, binary_name); g_free (binary_name); argv = g_ptr_array_new (); - g_ptr_array_add (argv, (gpointer) priv->path); + g_ptr_array_add (argv, (gpointer) dhcpcd_path); g_ptr_array_add (argv, (gpointer) "-B"); /* Don't background on lease (disable fork()) */ @@ -127,6 +112,9 @@ ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-L"); /* Disable built-in IPv4LL since we use avahi-autoipd */ + /* --noarp. Don't request or claim the address by ARP; this also disables IPv4LL. */ + g_ptr_array_add (argv, (gpointer) "-A"); + g_ptr_array_add (argv, (gpointer) "-G"); /* Let NM handle routing */ g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ @@ -140,7 +128,8 @@ ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-4"); #endif - if (hostname && strlen (hostname)) { + hostname = nm_dhcp_client_get_hostname (client); + if (hostname) { g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */ g_ptr_array_add (argv, (gpointer) hostname ); } @@ -152,34 +141,37 @@ ip4_start (NMDHCPClient *client, nm_log_dbg (LOGD_DHCP4, "running: %s", cmd_str); g_free (cmd_str); - if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, - &dhcpcd_child_setup, NULL, &pid, &error)) { + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + &dhcpcd_child_setup, NULL, &pid, &error)) { + g_assert (pid > 0); + nm_log_info (LOGD_DHCP4, "dhcpcd started with pid %d", pid); + nm_dhcp_client_watch_child (client, pid); + } else { nm_log_warn (LOGD_DHCP4, "dhcpcd failed to start. error: '%s'", error->message); g_error_free (error); - pid = -1; - } else - nm_log_info (LOGD_DHCP4, "dhcpcd started with pid %d", pid); + } g_free (pid_contents); g_ptr_array_free (argv, TRUE); - return pid; + return pid > 0 ? TRUE : FALSE; } -static GPid -ip6_start (NMDHCPClient *client, - GByteArray *dhcp_anycast_addr, - const char *hostname, +static gboolean +ip6_start (NMDhcpClient *client, + const char *dhcp_anycast_addr, gboolean info_only, + NMSettingIP6ConfigPrivacy privacy, const GByteArray *duid) { nm_log_warn (LOGD_DHCP6, "the dhcpcd backend does not support IPv6."); - return -1; + return FALSE; } static void -stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) { - NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); + NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); /* Chain up to parent */ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release, duid); @@ -195,17 +187,22 @@ stop (NMDHCPClient *client, gboolean release, const GByteArray *duid) /***************************************************/ static void -nm_dhcp_dhcpcd_init (NMDHCPDhcpcd *self) +nm_dhcp_dhcpcd_init (NMDhcpDhcpcd *self) { - NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (self); - - priv->path = nm_dhcp_dhcpcd_get_path (DHCPCD_PATH); + g_signal_connect (nm_dhcp_listener_get (), + NM_DHCP_LISTENER_EVENT, + G_CALLBACK (nm_dhcp_client_handle_event), + self); } static void dispose (GObject *object) { - NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (object); + NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (object); + + g_signal_handlers_disconnect_by_func (nm_dhcp_listener_get (), + G_CALLBACK (nm_dhcp_client_handle_event), + NM_DHCP_DHCPCD (object)); g_free (priv->pid_file); @@ -213,12 +210,12 @@ dispose (GObject *object) } static void -nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class) +nm_dhcp_dhcpcd_class_init (NMDhcpDhcpcdClass *dhcpcd_class) { - NMDHCPClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhcpcd_class); + NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS (dhcpcd_class); GObjectClass *object_class = G_OBJECT_CLASS (dhcpcd_class); - g_type_class_add_private (dhcpcd_class, sizeof (NMDHCPDhcpcdPrivate)); + g_type_class_add_private (dhcpcd_class, sizeof (NMDhcpDhcpcdPrivate)); /* virtual methods */ object_class->dispose = dispose; @@ -228,3 +225,13 @@ nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class) client_class->stop = stop; } +static void __attribute__((constructor)) +register_dhcp_dhclient (void) +{ + g_type_init (); + _nm_dhcp_client_register (NM_TYPE_DHCP_DHCPCD, + "dhcpcd", + nm_dhcp_dhcpcd_get_path, + NULL); +} + diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.h b/src/dhcp-manager/nm-dhcp-dhcpcd.h index fb6b0628..deed70e0 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.h +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.h @@ -16,8 +16,8 @@ * Copyright (C) 2005 - 2010 Red Hat, Inc. */ -#ifndef NM_DHCP_DHCPCD_H -#define NM_DHCP_DHCPCD_H +#ifndef __NETWORKMANAGER_DHCP_DHCPCD_H__ +#define __NETWORKMANAGER_DHCP_DHCPCD_H__ #include #include @@ -25,23 +25,21 @@ #include "nm-dhcp-client.h" #define NM_TYPE_DHCP_DHCPCD (nm_dhcp_dhcpcd_get_type ()) -#define NM_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcd)) -#define NM_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdClass)) +#define NM_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcd)) +#define NM_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) #define NM_IS_DHCP_DHCPCD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_DHCPCD)) #define NM_IS_DHCP_DHCPCD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_DHCPCD)) -#define NM_DHCP_DHCPCD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdClass)) +#define NM_DHCP_DHCPCD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_DHCPCD, NMDhcpDhcpcdClass)) typedef struct { - NMDHCPClient parent; -} NMDHCPDhcpcd; + NMDhcpClient parent; +} NMDhcpDhcpcd; typedef struct { - NMDHCPClientClass parent; -} NMDHCPDhcpcdClass; + NMDhcpClientClass parent; +} NMDhcpDhcpcdClass; GType nm_dhcp_dhcpcd_get_type (void); -const char *nm_dhcp_dhcpcd_get_path (const char *try_first); - -#endif /* NM_DHCP_DHCPCD_H */ +#endif /* __NETWORKMANAGER_DHCP_DHCPCD_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-helper.c b/src/dhcp-manager/nm-dhcp-helper.c index 4ddfafe1..7855f68c 100644 --- a/src/dhcp-manager/nm-dhcp-helper.c +++ b/src/dhcp-manager/nm-dhcp-helper.c @@ -18,184 +18,37 @@ * Copyright (C) 2007 - 2013 Red Hat, Inc. */ -/* for environ */ -#define _GNU_SOURCE +#include "config.h" -#include #include #include #include #include -#include - -#include +#include #define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" -/** - * _dbus_dict_open_write: - * @iter: A valid dbus message iterator - * @iter_dict: on return, a dict iterator to pass to further dict functions - * - * Start a dict in a dbus message. Should be paired with a call to - * _dbus_dict_close_write(). - * - * Returns: %TRUE on success, %FALSE on failure - */ -static dbus_bool_t -_dbus_dict_open_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) -{ - if (!iter || !iter_dict) - return FALSE; - - return dbus_message_iter_open_container (iter, - DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING - DBUS_TYPE_VARIANT_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, - iter_dict); -} - -/** - * _dbus_dict_close_write: - * @iter: valid dbus message iterator, same as passed to _dbus_dict_open_write() - * @iter_dict: a dbus dict iterator returned from _dbus_dict_open_write() - * - * End a dict element in a dbus message. Should be paired with a call to - * _dbus_dict_open_write(). - * - * Returns: %TRUE on success, %FALSE on failure - */ -static dbus_bool_t -_dbus_dict_close_write (DBusMessageIter *iter, DBusMessageIter *iter_dict) -{ - if (!iter || !iter_dict) - return FALSE; - - return dbus_message_iter_close_container (iter, iter_dict); -} - -static dbus_bool_t -_dbus_add_dict_entry_start (DBusMessageIter *iter_dict, - DBusMessageIter *iter_dict_entry, - const char *key, - const int value_type) -{ - if (!dbus_message_iter_open_container (iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, iter_dict_entry)) - return FALSE; - - if (!dbus_message_iter_append_basic (iter_dict_entry, DBUS_TYPE_STRING, &key)) - return FALSE; - - return TRUE; -} - - -static dbus_bool_t -_dbus_add_dict_entry_end (DBusMessageIter *iter_dict, - DBusMessageIter *iter_dict_entry, - DBusMessageIter *iter_dict_val) -{ - if (!dbus_message_iter_close_container (iter_dict_entry, iter_dict_val)) - return FALSE; - if (!dbus_message_iter_close_container (iter_dict, iter_dict_entry)) - return FALSE; - - return TRUE; -} - -static dbus_bool_t -_dbus_add_dict_entry_byte_array (DBusMessageIter *iter_dict, - const char *key, - const char *value, - const dbus_uint32_t value_len) -{ - DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; - dbus_uint32_t i; - - if (!_dbus_add_dict_entry_start (iter_dict, &iter_dict_entry, key, DBUS_TYPE_ARRAY)) - return FALSE; - - if (!dbus_message_iter_open_container (&iter_dict_entry, - DBUS_TYPE_VARIANT, - DBUS_TYPE_ARRAY_AS_STRING - DBUS_TYPE_BYTE_AS_STRING, - &iter_dict_val)) - return FALSE; - - if (!dbus_message_iter_open_container (&iter_dict_val, - DBUS_TYPE_ARRAY, - DBUS_TYPE_BYTE_AS_STRING, - &iter_array)) - return FALSE; - - for (i = 0; i < value_len; i++) { - if (!dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_BYTE, &(value[i]))) - return FALSE; - } - - if (!dbus_message_iter_close_container (&iter_dict_val, &iter_array)) - return FALSE; - - if (!_dbus_add_dict_entry_end (iter_dict, &iter_dict_entry, &iter_dict_val)) - return FALSE; - - return TRUE; -} - -/** - * _dbus_dict_append_byte_array: - * @iter_dict: A valid %DBusMessageIter returned from _dbus_dict_open_write() - * @key: The key of the dict item - * @value: The byte array - * @value_len: The length of the byte array, in bytes - * - * Add a byte array entry to the dict. - * - * Returns: %TRUE on success, %FALSE on failure - * - */ -static dbus_bool_t -_dbus_dict_append_byte_array (DBusMessageIter *iter_dict, - const char *key, - const char *value, - const dbus_uint32_t value_len) -{ - if (!key) - return FALSE; - if (!value && (value_len != 0)) - return FALSE; - return _dbus_add_dict_entry_byte_array (iter_dict, key, value, value_len); -} - - static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", NULL}; -static dbus_bool_t -build_message (DBusMessage * message) +static GVariant * +build_signal_parameters (void) { char **item; - dbus_bool_t success = FALSE; - DBusMessageIter iter, iter_dict; + GVariantBuilder builder; - dbus_message_iter_init_append (message, &iter); - if (!_dbus_dict_open_write (&iter, &iter_dict)) - goto out; + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); /* List environment and format for dbus dict */ for (item = environ; *item; item++) { char *name, *val, **p; /* Split on the = */ - name = strdup (*item); + name = g_strdup (*item); val = strchr (name, '='); - if (!val) + if (!val || val == name) goto next; *val++ = '\0'; - if (!strlen (val)) - val = NULL; /* Ignore non-DCHP-related environment variables */ for (p = (char **) ignore; *p; p++) { @@ -206,72 +59,82 @@ build_message (DBusMessage * message) /* Value passed as a byte array rather than a string, because there are * no character encoding guarantees with DHCP, and D-Bus requires * strings to be UTF-8. + * + * Note that we can't use g_variant_new_bytestring() here, because that + * includes the trailing '\0'. (??!?) */ - if (!_dbus_dict_append_byte_array (&iter_dict, - name, - val ? val : "\0", - val ? strlen (val) : 1)) { - fprintf (stderr, "Error: failed to add item '%s' to signal\n", name); - } + g_variant_builder_add (&builder, "{sv}", + name, + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + val, strlen (val), 1)); next: - free (name); + g_free (name); } - if (!_dbus_dict_close_write (&iter, &iter_dict)) - goto out; - - success = TRUE; - -out: - return success; + return g_variant_new ("(a{sv})", &builder); } #if !HAVE_DBUS_GLIB_100 -static DBusConnection * -shared_connection_init (void) +/* It doesn't matter that nm-dhcp-helper doesn't use dbus-glib itself; the + * workaround code is for if the daemon is built with old dbus-glib. + */ + +static gboolean ever_acquired = FALSE; + +static void +on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) { - DBusConnection * connection; - DBusError error; - int ret; + GMainLoop *loop = user_data; - dbus_connection_set_change_sigpipe (TRUE); + ever_acquired = TRUE; + g_main_loop_quit (loop); +} - dbus_error_init (&error); - connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (dbus_error_is_set (&error)) { - fprintf (stderr, "Error: could not get the system bus. Make sure " - "the message bus daemon is running! Message: (%s) %s\n", - error.name, - error.message); - goto error; +static void +on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + if (ever_acquired) { + g_print ("Lost D-Bus name: exiting\n"); + exit (0); + } else { + g_printerr ("Error: Could not acquire the NM DHCP client service.\n"); + exit (1); } +} - dbus_error_init (&error); - ret = dbus_bus_request_name (connection, "org.freedesktop.nm_dhcp_client", 0, &error); - if (dbus_error_is_set (&error)) { - fprintf (stderr, "Error: Could not acquire the NM DHCP client service. " - "Message: (%s) %s\n", - error.name, - error.message); - goto error; - } +static GDBusConnection * +shared_connection_init (void) +{ + GDBusConnection *connection; + GError *error = NULL; + GMainLoop *loop; - if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - fprintf (stderr, "Error: Could not acquire the NM DHCP client service " - "as it is already taken. Return: %d\n", - ret); - goto error; + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (!connection) { + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: could not get the system bus. Make sure " + "the message bus daemon is running! Message: %s\n", + error->message); + g_error_free (error); + return NULL; } - return connection; + loop = g_main_loop_new (NULL, FALSE); + g_bus_own_name_on_connection (connection, + "org.freedesktop.nm_dhcp_client", + 0, + on_name_acquired, + on_name_lost, + loop, NULL); + g_main_loop_run (loop); + g_main_loop_unref (loop); -error: - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - if (connection) - dbus_connection_unref (connection); - return NULL; + return connection; } #endif @@ -284,7 +147,7 @@ fatal_error (void) if (pid_str) pid = strtol (pid_str, NULL, 10); if (pid) { - fprintf (stderr, "Fatal error occured, killing dhclient instance with pid %d.\n", pid); + g_printerr ("Fatal error occured, killing dhclient instance with pid %d.\n", pid); kill (pid, SIGTERM); } @@ -294,52 +157,46 @@ fatal_error (void) int main (int argc, char *argv[]) { - DBusConnection *connection; - DBusMessage *message; - dbus_bool_t result; - DBusError error; - - dbus_connection_set_change_sigpipe (TRUE); + GDBusConnection *connection; + GError *error = NULL; - dbus_error_init (&error); - connection = dbus_connection_open_private ("unix:path=" NMRUNDIR "/private-dhcp", &error); + connection = g_dbus_connection_new_for_address_sync ("unix:path=" NMRUNDIR "/private-dhcp", + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, NULL, &error); if (!connection) { #if !HAVE_DBUS_GLIB_100 connection = shared_connection_init (); #endif if (!connection) { - fprintf (stderr, "Error: could not connect to NetworkManager DBus socket: (%s) %s\n", - error.name, error.message); - dbus_error_free (&error); + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: could not connect to NetworkManager D-Bus socket: %s\n", + error->message); + g_error_free (error); fatal_error (); } } - dbus_connection_set_exit_on_disconnect (connection, FALSE); - message = dbus_message_new_signal ("/", NM_DHCP_CLIENT_DBUS_IFACE, "Event"); - if (message == NULL) { - fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n"); + if (!g_dbus_connection_emit_signal (connection, + NULL, + "/", + NM_DHCP_CLIENT_DBUS_IFACE, + "Event", + build_signal_parameters (), + &error)) { + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: Could not send DHCP Event signal: %s\n", error->message); + g_error_free (error); fatal_error (); } - /* Dump environment variables into the message */ - result = build_message (message); - if (result == FALSE) { - fprintf (stderr, "Error: Not enough memory to send DHCP Event signal.\n"); + if (!g_dbus_connection_flush_sync (connection, NULL, &error)) { + g_dbus_error_strip_remote_error (error); + g_printerr ("Error: Could not flush D-Bus connection: %s\n", error->message); + g_error_free (error); fatal_error (); } - /* queue the message */ - result = dbus_connection_send (connection, message, NULL); - if (!result) { - fprintf (stderr, "Error: Could not send send DHCP Event signal.\n"); - fatal_error (); - } - dbus_message_unref (message); - - /* Send out the message */ - dbus_connection_flush (connection); - + g_object_unref (connection); return 0; } diff --git a/src/dhcp-manager/nm-dhcp-listener.c b/src/dhcp-manager/nm-dhcp-listener.c new file mode 100644 index 00000000..b995c348 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-listener.c @@ -0,0 +1,290 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-dhcp-listener.h" +#include "nm-logging.h" +#include "nm-dbus-manager.h" +#include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" +#include "NetworkManagerUtils.h" + +#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" +#define PRIV_SOCK_PATH NMRUNDIR "/private-dhcp" +#define PRIV_SOCK_TAG "dhcp" + +typedef struct { + NMDBusManager * dbus_mgr; + guint new_conn_id; + guint dis_conn_id; + GHashTable * proxies; + DBusGProxy * proxy; +} NMDhcpListenerPrivate; + +#define NM_DHCP_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_LISTENER, NMDhcpListenerPrivate)) + +G_DEFINE_TYPE (NMDhcpListener, nm_dhcp_listener, G_TYPE_OBJECT) + +enum { + EVENT, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/***************************************************/ + +static char * +garray_to_string (GArray *array, const char *key) +{ + GString *str; + int i; + unsigned char c; + char *converted = NULL; + + g_return_val_if_fail (array != NULL, NULL); + + /* Since the DHCP options come through environment variables, they should + * already be UTF-8 safe, but just make sure. + */ + str = g_string_sized_new (array->len); + for (i = 0; i < array->len; i++) { + c = array->data[i]; + + /* Convert NULLs to spaces and non-ASCII characters to ? */ + if (c == '\0') + c = ' '; + else if (c > 127) + c = '?'; + str = g_string_append_c (str, c); + } + str = g_string_append_c (str, '\0'); + + converted = str->str; + if (!g_utf8_validate (converted, -1, NULL)) + nm_log_warn (LOGD_DHCP, "DHCP option '%s' couldn't be converted to UTF-8", key); + g_string_free (str, FALSE); + return converted; +} + +static char * +get_option (GHashTable *hash, const char *key) +{ + GValue *value; + + value = g_hash_table_lookup (hash, key); + if (value == NULL) + return NULL; + + if (G_VALUE_TYPE (value) != DBUS_TYPE_G_UCHAR_ARRAY) { + nm_log_warn (LOGD_DHCP, "unexpected key %s value type was not " + "DBUS_TYPE_G_UCHAR_ARRAY", + (char *) key); + return NULL; + } + + return garray_to_string ((GArray *) g_value_get_boxed (value), key); +} + +static void +handle_event (DBusGProxy *proxy, + GHashTable *options, + gpointer user_data) +{ + NMDhcpListener *self = NM_DHCP_LISTENER (user_data); + char *iface = NULL; + char *pid_str = NULL; + char *reason = NULL; + gint pid; + gboolean handled = FALSE; + + iface = get_option (options, "interface"); + if (iface == NULL) { + nm_log_warn (LOGD_DHCP, "DHCP event: didn't have associated interface."); + goto out; + } + + pid_str = get_option (options, "pid"); + pid = nm_utils_ascii_str_to_int64 (pid_str, 10, 0, G_MAXINT32, -1); + if (pid == -1) { + nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); + goto out; + } + + reason = get_option (options, "reason"); + if (reason == NULL) { + nm_log_warn (LOGD_DHCP, "(pid %d) DHCP event didn't have a reason", pid); + goto out; + } + + g_signal_emit (self, signals[EVENT], 0, iface, pid, options, reason, &handled); + if (!handled) { + if (g_ascii_strcasecmp (reason, "RELEASE") == 0) { + /* Ignore event when the dhcp client gets killed and we receive its last message */ + nm_log_dbg (LOGD_DHCP, "(pid %d) unhandled RELEASE DHCP event for interface %s", pid, iface); + } else + nm_log_warn (LOGD_DHCP, "(pid %d) unhandled DHCP event for interface %s", pid, iface); + } + +out: + g_free (iface); + g_free (pid_str); + g_free (reason); +} + +#if HAVE_DBUS_GLIB_100 +static void +new_connection_cb (NMDBusManager *mgr, + DBusGConnection *connection, + NMDhcpListener *self) +{ + DBusGProxy *proxy; + + /* Create a new proxy for the client */ + proxy = dbus_g_proxy_new_for_peer (connection, "/", NM_DHCP_CLIENT_DBUS_IFACE); + dbus_g_proxy_add_signal (proxy, "Event", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (proxy, "Event", G_CALLBACK (handle_event), self, NULL); + + g_hash_table_insert (NM_DHCP_LISTENER_GET_PRIVATE (self)->proxies, connection, proxy); +} + +static void +dis_connection_cb (NMDBusManager *mgr, + DBusGConnection *connection, + NMDhcpListener *self) +{ + NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self); + DBusGProxy *proxy; + + proxy = g_hash_table_lookup (priv->proxies, connection); + if (proxy) { + dbus_g_proxy_disconnect_signal (proxy, "Event", G_CALLBACK (handle_event), self); + g_hash_table_remove (priv->proxies, connection); + } +} +#endif + +/***************************************************/ + +NMDhcpListener * +nm_dhcp_listener_get (void) +{ + static NMDhcpListener *singleton = NULL; + + if (G_UNLIKELY (singleton == NULL)) + singleton = g_object_new (NM_TYPE_DHCP_LISTENER, NULL); + g_assert (singleton); + return singleton; +} + +static void +nm_dhcp_listener_init (NMDhcpListener *self) +{ + NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (self); +#if !HAVE_DBUS_GLIB_100 + DBusGConnection *g_connection; +#endif + + /* Maps DBusGConnection :: DBusGProxy */ + priv->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + + priv->dbus_mgr = nm_dbus_manager_get (); + +#if HAVE_DBUS_GLIB_100 + /* Register the socket our DHCP clients will return lease info on */ + nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); + priv->new_conn_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, + G_CALLBACK (new_connection_cb), + self); + priv->dis_conn_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, + G_CALLBACK (dis_connection_cb), + self); +#else + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (g_connection, + "org.freedesktop.nm_dhcp_client", + "/", + NM_DHCP_CLIENT_DBUS_IFACE); + g_assert (priv->proxy); + dbus_g_proxy_add_signal (priv->proxy, "Event", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->proxy, "Event", G_CALLBACK (handle_event), self, NULL); +#endif +} + +static void +dispose (GObject *object) +{ + NMDhcpListenerPrivate *priv = NM_DHCP_LISTENER_GET_PRIVATE (object); + + if (priv->new_conn_id) { + g_signal_handler_disconnect (priv->dbus_mgr, priv->new_conn_id); + priv->new_conn_id = 0; + } + if (priv->dis_conn_id) { + g_signal_handler_disconnect (priv->dbus_mgr, priv->dis_conn_id); + priv->dis_conn_id = 0; + } + priv->dbus_mgr = NULL; + + if (priv->proxies) { + g_hash_table_destroy (priv->proxies); + priv->proxies = NULL; + } + g_clear_object (&priv->proxy); + + G_OBJECT_CLASS (nm_dhcp_listener_parent_class)->dispose (object); +} + +static void +nm_dhcp_listener_class_init (NMDhcpListenerClass *listener_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (listener_class); + + g_type_class_add_private (listener_class, sizeof (NMDhcpListenerPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + + /* signals */ + signals[EVENT] = + g_signal_new (NM_DHCP_LISTENER_EVENT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, 0, + g_signal_accumulator_true_handled, + NULL, NULL, + G_TYPE_BOOLEAN, /* listeners return TRUE if handled */ + 4, + G_TYPE_STRING, /* iface */ + G_TYPE_INT, /* pid */ + G_TYPE_HASH_TABLE, /* options */ + G_TYPE_STRING); /* reason */ +} diff --git a/src/dhcp-manager/nm-dhcp-listener.h b/src/dhcp-manager/nm-dhcp-listener.h new file mode 100644 index 00000000..15ec0531 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-listener.h @@ -0,0 +1,39 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DHCP_LISTENER_H__ +#define __NETWORKMANAGER_DHCP_LISTENER_H__ + +#include +#include + +#define NM_TYPE_DHCP_LISTENER (nm_dhcp_listener_get_type ()) +#define NM_DHCP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_LISTENER, NMDhcpListener)) +#define NM_IS_DHCP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_LISTENER)) +#define NM_DHCP_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_LISTENER, NMDhcpListenerClass)) + +#define NM_DHCP_LISTENER_EVENT "event" + +typedef GObject NMDhcpListener; +typedef GObjectClass NMDhcpListenerClass; + +GType nm_dhcp_listener_get_type (void); + +NMDhcpListener *nm_dhcp_listener_get (void); + +#endif /* __NETWORKMANAGER_DHCP_LISTENER_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index ab6966cb..f936f45c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -21,9 +21,9 @@ */ #include "config.h" + #include #include -#include #include #include #include @@ -37,31 +37,15 @@ #include "nm-dhcp-manager.h" #include "nm-dhcp-dhclient.h" #include "nm-dhcp-dhcpcd.h" +#include "nm-dhcp-systemd.h" #include "nm-logging.h" -#include "nm-dbus-manager.h" #include "nm-config.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "NetworkManagerUtils.h" -GQuark -nm_dhcp_manager_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm_dhcp_manager_error"); - - return ret; -} - -#define NM_DHCP_CLIENT_DBUS_IFACE "org.freedesktop.nm_dhcp_client" - #define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */ -#define PRIV_SOCK_PATH NMRUNDIR "/private-dhcp" -#define PRIV_SOCK_TAG "dhcp" - /* default to installed helper, but can be modified for testing */ const char *nm_dhcp_helper_path = LIBEXECDIR "/nm-dhcp-helper"; @@ -69,336 +53,186 @@ typedef GSList * (*GetLeaseConfigFunc) (const char *iface, const char *uuid, gbo typedef struct { GType client_type; - GetLeaseConfigFunc get_lease_ip_configs_func; - - NMDBusManager * dbus_mgr; - guint new_conn_id; - guint dis_conn_id; - GHashTable * proxies; - GHashTable * clients; - DBusGProxy * proxy; char * default_hostname; -} NMDHCPManagerPrivate; +} NMDhcpManagerPrivate; + +#define NM_DHCP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_MANAGER, NMDhcpManagerPrivate)) +G_DEFINE_TYPE (NMDhcpManager, nm_dhcp_manager, G_TYPE_OBJECT) -#define NM_DHCP_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_MANAGER, NMDHCPManagerPrivate)) +/***************************************************/ + +typedef struct { + GType gtype; + const char *name; + NMDhcpClientGetPathFunc get_path_func; + NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func; +} ClientDesc; -G_DEFINE_TYPE (NMDHCPManager, nm_dhcp_manager, G_TYPE_OBJECT) +static GSList *client_descs = NULL; -static char * -garray_to_string (GArray *array, const char *key) +void +_nm_dhcp_client_register (GType gtype, + const char *name, + NMDhcpClientGetPathFunc get_path_func, + NMDhcpClientGetLeaseConfigsFunc get_lease_configs_func) { - GString *str; - int i; - unsigned char c; - char *converted = NULL; + ClientDesc *desc; + GSList *iter; - g_return_val_if_fail (array != NULL, NULL); + g_return_if_fail (gtype != G_TYPE_INVALID); + g_return_if_fail (name != NULL); - /* Since the DHCP options come through environment variables, they should - * already be UTF-8 safe, but just make sure. - */ - str = g_string_sized_new (array->len); - for (i = 0; i < array->len; i++) { - c = array->data[i]; - - /* Convert NULLs to spaces and non-ASCII characters to ? */ - if (c == '\0') - c = ' '; - else if (c > 127) - c = '?'; - str = g_string_append_c (str, c); + for (iter = client_descs; iter; iter = iter->next) { + desc = iter->data; + g_return_if_fail (desc->gtype != gtype); + g_return_if_fail (strcmp (desc->name, name) != 0); } - str = g_string_append_c (str, '\0'); - converted = str->str; - if (!g_utf8_validate (converted, -1, NULL)) - nm_log_warn (LOGD_DHCP, "DHCP option '%s' couldn't be converted to UTF-8", key); - g_string_free (str, FALSE); - return converted; + desc = g_slice_new0 (ClientDesc); + desc->gtype = gtype; + desc->name = name; + desc->get_path_func = get_path_func; + desc->get_lease_configs_func = get_lease_configs_func; + client_descs = g_slist_prepend (client_descs, desc); } -static NMDHCPClient * -get_client_for_pid (NMDHCPManager *manager, GPid pid) +static ClientDesc * +find_client_desc (const char *name, GType gtype) { - NMDHCPManagerPrivate *priv; - GHashTableIter iter; - gpointer value; + GSList *iter; - g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); - - priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); + g_return_val_if_fail (name || gtype, NULL); - g_hash_table_iter_init (&iter, priv->clients); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - NMDHCPClient *candidate = NM_DHCP_CLIENT (value); + for (iter = client_descs; iter; iter = iter->next) { + ClientDesc *desc = iter->data; - if (nm_dhcp_client_get_pid (candidate) == pid) - return candidate; + if (name && strcmp (desc->name, name) != 0) + continue; + if (gtype && desc->gtype != gtype) + continue; + return desc; } - return NULL; } -static NMDHCPClient * -get_client_for_iface (NMDHCPManager *manager, - const char *iface, - gboolean ip6) +static GType +is_client_enabled (const char *name, GError **error) +{ + ClientDesc *desc; + + desc = find_client_desc (name, G_TYPE_INVALID); + if (desc && (!desc->get_path_func || desc->get_path_func())) + return desc->gtype; + + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + _("'%s' support not found or not enabled."), + name); + return G_TYPE_INVALID; +} + +/***************************************************/ + +static NMDhcpClient * +get_client_for_ifindex (NMDhcpManager *manager, int ifindex, gboolean ip6) { - NMDHCPManagerPrivate *priv; + NMDhcpManagerPrivate *priv; GHashTableIter iter; gpointer value; g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); - g_return_val_if_fail (iface, NULL); + g_return_val_if_fail (ifindex > 0, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); g_hash_table_iter_init (&iter, priv->clients); while (g_hash_table_iter_next (&iter, NULL, &value)) { - NMDHCPClient *candidate = NM_DHCP_CLIENT (value); + NMDhcpClient *candidate = NM_DHCP_CLIENT (value); - if ( !strcmp (iface, nm_dhcp_client_get_iface (candidate)) - && (nm_dhcp_client_get_ipv6 (candidate) == ip6)) + if ( nm_dhcp_client_get_ifindex (candidate) == ifindex + && nm_dhcp_client_get_ipv6 (candidate) == ip6) return candidate; } return NULL; } -static char * -get_option (GHashTable *hash, const char *key) -{ - GValue *value; - - value = g_hash_table_lookup (hash, key); - if (value == NULL) - return NULL; - - if (G_VALUE_TYPE (value) != DBUS_TYPE_G_UCHAR_ARRAY) { - nm_log_warn (LOGD_DHCP, "unexpected key %s value type was not " - "DBUS_TYPE_G_UCHAR_ARRAY", - (char *) key); - return NULL; - } - - return garray_to_string ((GArray *) g_value_get_boxed (value), key); -} - -static void -nm_dhcp_manager_handle_event (DBusGProxy *proxy, - GHashTable *options, - gpointer user_data) -{ - NMDHCPManager *manager = NM_DHCP_MANAGER (user_data); - NMDHCPClient *client; - char *iface = NULL; - char *pid_str = NULL; - char *reason = NULL; - long pid; - - iface = get_option (options, "interface"); - if (iface == NULL) { - nm_log_warn (LOGD_DHCP, "DHCP event: didn't have associated interface."); - goto out; - } - - pid_str = get_option (options, "pid"); - pid = nm_utils_ascii_str_to_int64 (pid_str, 10, 0, LONG_MAX, -1); - if (pid == -1 || pid != (GPid)pid) { - nm_log_warn (LOGD_DHCP, "DHCP event: couldn't convert PID '%s' to an integer", pid_str ? pid_str : "(null)"); - goto out; - } - - reason = get_option (options, "reason"); - client = get_client_for_pid (manager, (GPid) pid); - if (client == NULL) { - if (reason && g_ascii_strcasecmp (reason, "RELEASE") == 0) { - /* This happens regularly, when the dhcp client gets killed and we receive its last message. - * Don't log a warning in this case. */ - nm_log_dbg (LOGD_DHCP, "(pid %ld) unhandled RELEASE DHCP event for interface %s", pid, iface); - } else - nm_log_warn (LOGD_DHCP, "(pid %ld) unhandled DHCP event for interface %s", pid, iface); - goto out; - } - - if (strcmp (iface, nm_dhcp_client_get_iface (client))) { - nm_log_warn (LOGD_DHCP, "(pid %ld) received DHCP event from unexpected interface '%s' (expected '%s')", - pid, iface, nm_dhcp_client_get_iface (client)); - goto out; - } - - if (reason == NULL) { - nm_log_warn (LOGD_DHCP, "(pid %ld) DHCP event didn't have a reason", pid); - goto out; - } - - nm_dhcp_client_new_options (client, options, reason); - -out: - g_free (iface); - g_free (pid_str); - g_free (reason); -} - -#if HAVE_DBUS_GLIB_100 -static void -new_connection_cb (NMDBusManager *mgr, - DBusGConnection *connection, - NMDHCPManager *self) -{ - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - DBusGProxy *proxy; - - /* Create a new proxy for the client */ - proxy = dbus_g_proxy_new_for_peer (connection, "/", NM_DHCP_CLIENT_DBUS_IFACE); - dbus_g_proxy_add_signal (proxy, - "Event", - DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (proxy, - "Event", - G_CALLBACK (nm_dhcp_manager_handle_event), - self, - NULL); - g_hash_table_insert (priv->proxies, connection, proxy); -} - -static void -dis_connection_cb (NMDBusManager *mgr, - DBusGConnection *connection, - NMDHCPManager *self) -{ - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - DBusGProxy *proxy; - - proxy = g_hash_table_lookup (priv->proxies, connection); - if (proxy) { - dbus_g_proxy_disconnect_signal (proxy, - "Event", - G_CALLBACK (nm_dhcp_manager_handle_event), - self); - g_hash_table_remove (priv->proxies, connection); - } -} -#endif - static GType get_client_type (const char *client, GError **error) { - const char *dhclient_path = NULL; - const char *dhcpcd_path = NULL; - - /* If a client was disabled at build-time, its *_PATH define will be - * an empty string. - */ - /* coverity[array_null] */ - if (DHCLIENT_PATH && strlen (DHCLIENT_PATH)) - dhclient_path = nm_dhcp_dhclient_get_path (DHCLIENT_PATH); - /* coverity[array_null] */ - if (DHCPCD_PATH && strlen (DHCPCD_PATH)) - dhcpcd_path = nm_dhcp_dhcpcd_get_path (DHCPCD_PATH); - - if (!client) { - if (dhclient_path) - return NM_TYPE_DHCP_DHCLIENT; - else if (dhcpcd_path) - return NM_TYPE_DHCP_DHCPCD; - else { - g_set_error_literal (error, - NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, - _("no usable DHCP client could be found.")); - return G_TYPE_INVALID; - } - } - - if (!strcmp (client, "dhclient")) { - if (!dhclient_path) { - g_set_error_literal (error, - NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, - _("'dhclient' could be found.")); - return G_TYPE_INVALID; + GType client_gtype; + + if (client) + client_gtype = is_client_enabled (client, error); + else { + /* Fallbacks */ + client_gtype = is_client_enabled ("dhclient", NULL); + if (client_gtype == G_TYPE_INVALID) + client_gtype = is_client_enabled ("dhcpcd", NULL); + if (client_gtype == G_TYPE_INVALID) + client_gtype = is_client_enabled ("internal", NULL); + if (client_gtype == G_TYPE_INVALID) { + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + _("no usable DHCP client could be found.")); } - return NM_TYPE_DHCP_DHCLIENT; } - - if (!strcmp (client, "dhcpcd")) { - if (!dhcpcd_path) { - g_set_error_literal (error, - NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, - _("'dhcpcd' could be found.")); - return G_TYPE_INVALID; - } - return NM_TYPE_DHCP_DHCPCD; - } - - g_set_error (error, - NM_DHCP_MANAGER_ERROR, NM_DHCP_MANAGER_ERROR_BAD_CLIENT, - _("unsupported DHCP client '%s'"), client); - return G_TYPE_INVALID; + return client_gtype; } -#define REMOVE_ID_TAG "remove-id" -#define TIMEOUT_ID_TAG "timeout-id" +static void client_state_changed (NMDhcpClient *client, + NMDhcpState state, + GObject *ip_config, + GHashTable *options, + NMDhcpManager *self); static void -remove_client (NMDHCPManager *self, NMDHCPClient *client) +remove_client (NMDhcpManager *self, NMDhcpClient *client) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - guint id; - - id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (client), REMOVE_ID_TAG)); - if (id) - g_signal_handler_disconnect (client, id); - - id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (client), TIMEOUT_ID_TAG)); - if (id) - g_signal_handler_disconnect (client, id); + g_signal_handlers_disconnect_by_func (client, client_state_changed, self); /* Stopping the client is left up to the controlling device * explicitly since we may want to quit NetworkManager but not terminate * the DHCP client. */ - g_hash_table_remove (priv->clients, client); + g_hash_table_remove (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client); } static void -add_client (NMDHCPManager *self, NMDHCPClient *client) +client_state_changed (NMDhcpClient *client, + NMDhcpState state, + GObject *ip_config, + GHashTable *options, + NMDhcpManager *self) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - guint id; - - id = g_signal_connect_swapped (client, NM_DHCP_CLIENT_SIGNAL_REMOVE, G_CALLBACK (remove_client), self); - g_object_set_data (G_OBJECT (client), REMOVE_ID_TAG, GUINT_TO_POINTER (id)); - - id = g_signal_connect_swapped (client, NM_DHCP_CLIENT_SIGNAL_TIMEOUT, G_CALLBACK (remove_client), self); - g_object_set_data (G_OBJECT (client), TIMEOUT_ID_TAG, GUINT_TO_POINTER (id)); - - g_hash_table_insert (priv->clients, client, g_object_ref (client)); + if (state >= NM_DHCP_STATE_TIMEOUT) + remove_client (self, client); } -static NMDHCPClient * -client_start (NMDHCPManager *self, +static NMDhcpClient * +client_start (NMDhcpManager *self, const char *iface, + int ifindex, const GByteArray *hwaddr, const char *uuid, - guint priority, + guint32 priority, gboolean ipv6, const char *dhcp_client_id, guint32 timeout, - GByteArray *dhcp_anycast_addr, + const char *dhcp_anycast_addr, const char *hostname, - gboolean info_only) + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy, + const char *last_ip4_address) { - NMDHCPManagerPrivate *priv; - NMDHCPClient *client; + NMDhcpManagerPrivate *priv; + NMDhcpClient *client; gboolean success = FALSE; g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (uuid != NULL, NULL); priv = NM_DHCP_MANAGER_GET_PRIVATE (self); @@ -407,32 +241,34 @@ client_start (NMDHCPManager *self, g_return_val_if_fail (priv->client_type != 0, NULL); /* Kill any old client instance */ - client = get_client_for_iface (self, iface, ipv6); + client = get_client_for_ifindex (self, ifindex, ipv6); if (client) { - nm_dhcp_client_stop (client, FALSE); + g_object_ref (client); remove_client (self, client); + nm_dhcp_client_stop (client, FALSE); + g_object_unref (client); } /* And make a new one */ client = g_object_new (priv->client_type, NM_DHCP_CLIENT_INTERFACE, iface, + NM_DHCP_CLIENT_IFINDEX, ifindex, NM_DHCP_CLIENT_HWADDR, hwaddr, NM_DHCP_CLIENT_IPV6, ipv6, NM_DHCP_CLIENT_UUID, uuid, NM_DHCP_CLIENT_PRIORITY, priority, NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT, NULL); - g_return_val_if_fail (client != NULL, NULL); - add_client (self, client); + g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client)); + g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); if (ipv6) - success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, hostname, info_only); + success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, hostname, info_only, privacy); else - success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname); + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address); if (!success) { remove_client (self, client); - g_object_unref (client); client = NULL; } @@ -440,134 +276,105 @@ client_start (NMDHCPManager *self, } static const char * -get_send_hostname (NMDHCPManager *self, const char *setting_hostname) +get_send_hostname (NMDhcpManager *self, const char *setting_hostname) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); /* Always prefer the explicit dhcp-send-hostname if given */ return setting_hostname ? setting_hostname : priv->default_hostname; } -/* Caller owns a reference to the NMDHCPClient on return */ -NMDHCPClient * -nm_dhcp_manager_start_ip4 (NMDHCPManager *self, +/* Caller owns a reference to the NMDhcpClient on return */ +NMDhcpClient * +nm_dhcp_manager_start_ip4 (NMDhcpManager *self, const char *iface, + int ifindex, const GByteArray *hwaddr, const char *uuid, - guint priority, - NMSettingIP4Config *s_ip4, + guint32 priority, + gboolean send_hostname, + const char *dhcp_hostname, + const char *dhcp_client_id, guint32 timeout, - GByteArray *dhcp_anycast_addr) + const char *dhcp_anycast_addr, + const char *last_ip_address) { - const char *hostname = NULL, *method; - gboolean send_hostname; + const char *hostname = NULL; - g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - method = nm_setting_ip4_config_get_method (s_ip4); - g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL); - - send_hostname = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4); if (send_hostname) - hostname = get_send_hostname (self, nm_setting_ip4_config_get_dhcp_hostname (s_ip4)); - - return client_start (self, iface, hwaddr, uuid, priority, FALSE, - nm_setting_ip4_config_get_dhcp_client_id (s_ip4), - timeout, dhcp_anycast_addr, hostname, FALSE); + hostname = get_send_hostname (self, dhcp_hostname); + return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, + dhcp_client_id, timeout, dhcp_anycast_addr, hostname, + FALSE, 0, last_ip_address); } -/* Caller owns a reference to the NMDHCPClient on return */ -NMDHCPClient * -nm_dhcp_manager_start_ip6 (NMDHCPManager *self, +/* Caller owns a reference to the NMDhcpClient on return */ +NMDhcpClient * +nm_dhcp_manager_start_ip6 (NMDhcpManager *self, const char *iface, + int ifindex, const GByteArray *hwaddr, const char *uuid, - guint priority, - NMSettingIP6Config *s_ip6, + guint32 priority, + gboolean send_hostname, + const char *dhcp_hostname, guint32 timeout, - GByteArray *dhcp_anycast_addr, - gboolean info_only) + const char *dhcp_anycast_addr, + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy) { - const char *hostname; + const char *hostname = NULL; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); - hostname = get_send_hostname (self, nm_setting_ip6_config_get_dhcp_hostname (s_ip6)); - - return client_start (self, iface, hwaddr, uuid, priority, TRUE, - NULL, timeout, dhcp_anycast_addr, hostname, info_only); + if (send_hostname) + hostname = get_send_hostname (self, dhcp_hostname); + return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE, + NULL, timeout, dhcp_anycast_addr, hostname, info_only, + privacy, NULL); } void -nm_dhcp_manager_set_default_hostname (NMDHCPManager *manager, const char *hostname) +nm_dhcp_manager_set_default_hostname (NMDhcpManager *manager, const char *hostname) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (manager); g_clear_pointer (&priv->default_hostname, g_free); /* Never send 'localhost'-type names to the DHCP server */ - if (g_strcmp0 (hostname, "localhost.localdomain") == 0 || - g_strcmp0 (hostname, "localhost6.localdomain6") == 0) + if (!nm_utils_is_specific_hostname (hostname)) return; priv->default_hostname = g_strdup (hostname); } GSList * -nm_dhcp_manager_get_lease_ip_configs (NMDHCPManager *self, +nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, const char *iface, const char *uuid, - gboolean ipv6) + gboolean ipv6, + guint32 default_route_metric) { - NMDHCPManagerPrivate *priv; + ClientDesc *desc; g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (iface != NULL, NULL); g_return_val_if_fail (uuid != NULL, NULL); - priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - - if (priv->get_lease_ip_configs_func) - return priv->get_lease_ip_configs_func (iface, uuid, ipv6); + desc = find_client_desc (NULL, NM_DHCP_MANAGER_GET_PRIVATE (self)->client_type); + if (desc && desc->get_lease_configs_func) + return desc->get_lease_configs_func (iface, uuid, ipv6, default_route_metric); return NULL; } -NMIP4Config * -nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client, - const char *iface, - GHashTable *options, - const char *reason) -{ - NMDHCPClient *client; - NMIP4Config *config; - GType client_type; - GError *error = NULL; - - client_type = get_client_type (dhcp_client, &error); - if (!client_type) { - nm_log_err (LOGD_DHCP4, "error: %s", error ? error->message : "(unknown)"); - g_clear_error (&error); - return NULL; - } - - client = (NMDHCPClient *) g_object_new (client_type, - NM_DHCP_CLIENT_INTERFACE, iface, - NULL); - g_return_val_if_fail (client != NULL, NULL); - nm_dhcp_client_new_options (client, options, reason); - config = nm_dhcp_client_get_ip4_config (client, TRUE); - g_object_unref (client); - - return config; -} - /***************************************************/ -NMDHCPManager * +NMDhcpManager * nm_dhcp_manager_get (void) { - static NMDHCPManager *singleton = NULL; + static NMDhcpManager *singleton = NULL; if (G_UNLIKELY (singleton == NULL)) singleton = g_object_new (NM_TYPE_DHCP_MANAGER, NULL); @@ -576,67 +383,48 @@ nm_dhcp_manager_get (void) } static void -nm_dhcp_manager_init (NMDHCPManager *self) +nm_dhcp_manager_init (NMDhcpManager *self) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self); + NMConfig *config = nm_config_get (); const char *client; GError *error = NULL; -#if !HAVE_DBUS_GLIB_100 - DBusGConnection *g_connection; -#endif + GSList *iter; - /* Maps DBusGConnection :: DBusGProxy */ - priv->proxies = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + for (iter = client_descs; iter; iter = iter->next) { + ClientDesc *desc = iter->data; + + nm_log_dbg (LOGD_DHCP, "Registered DHCP client '%s' (%s)", + desc->name, g_type_name (desc->gtype)); + } /* Client-specific setup */ - client = nm_config_get_dhcp_client (nm_config_get ()); - priv->client_type = get_client_type (client, &error); + client = nm_config_get_dhcp_client (config); + if (nm_config_get_configure_and_quit (config)) { + if (g_strcmp0 (client, "internal") != 0) + nm_log_warn (LOGD_DHCP, "Using internal DHCP client since configure-and-quit is set."); + client = "internal"; + } - if (priv->client_type == NM_TYPE_DHCP_DHCLIENT) - priv->get_lease_ip_configs_func = nm_dhcp_dhclient_get_lease_ip_configs; - else if (priv->client_type == G_TYPE_INVALID) { + priv->client_type = get_client_type (client, &error); + if (priv->client_type == G_TYPE_INVALID) { nm_log_warn (LOGD_DHCP, "No usable DHCP client found (%s)! DHCP configurations will fail.", error->message); + } else { + nm_log_dbg (LOGD_DHCP, "Using DHCP client '%s'", find_client_desc (NULL, priv->client_type)->name); + } g_clear_error (&error); priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_object_unref); - g_assert (priv->clients); - - priv->dbus_mgr = nm_dbus_manager_get (); - -#if HAVE_DBUS_GLIB_100 - /* Register the socket our DHCP clients will return lease info on */ - nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); - priv->new_conn_id = g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, - (GCallback) new_connection_cb, - self); - priv->dis_conn_id = g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, - (GCallback) dis_connection_cb, - self); -#else - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - priv->proxy = dbus_g_proxy_new_for_name (g_connection, - "org.freedesktop.nm_dhcp_client", - "/", - NM_DHCP_CLIENT_DBUS_IFACE); - g_assert (priv->proxy); - dbus_g_proxy_add_signal (priv->proxy, "Event", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "Event", - G_CALLBACK (nm_dhcp_manager_handle_event), - self, - NULL); -#endif } static void dispose (GObject *object) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object); GList *values, *iter; if (priv->clients) { @@ -646,30 +434,13 @@ dispose (GObject *object) g_list_free (values); } - if (priv->new_conn_id) { - g_signal_handler_disconnect (priv->dbus_mgr, priv->new_conn_id); - priv->new_conn_id = 0; - } - if (priv->dis_conn_id) { - g_signal_handler_disconnect (priv->dbus_mgr, priv->dis_conn_id); - priv->dis_conn_id = 0; - } - priv->dbus_mgr = NULL; - - if (priv->proxies) { - g_hash_table_destroy (priv->proxies); - priv->proxies = NULL; - } - if (priv->proxy) - g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->dispose (object); } static void finalize (GObject *object) { - NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object); + NMDhcpManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object); g_free (priv->default_hostname); @@ -680,11 +451,11 @@ finalize (GObject *object) } static void -nm_dhcp_manager_class_init (NMDHCPManagerClass *manager_class) +nm_dhcp_manager_class_init (NMDhcpManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - g_type_class_add_private (manager_class, sizeof (NMDHCPManagerPrivate)); + g_type_class_add_private (manager_class, sizeof (NMDhcpManagerPrivate)); /* virtual methods */ object_class->finalize = finalize; diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index efdd4378..bf6cc778 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -19,81 +19,71 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_DHCP_MANAGER_H -#define NM_DHCP_MANAGER_H +#ifndef __NETWORKMANAGER_DHCP_MANAGER_H__ +#define __NETWORKMANAGER_DHCP_MANAGER_H__ #include #include -#include -#include - #include "nm-dhcp-client.h" #include "nm-ip4-config.h" #include "nm-dhcp4-config.h" -typedef enum { - NM_DHCP_MANAGER_ERROR_BAD_CLIENT = 0, /*< nick=BadClient >*/ - NM_DHCP_MANAGER_ERROR_INTERNAL = 1, /*< nick=InternalError >*/ -} NMDHCPManagerError; - -#define NM_DHCP_MANAGER_ERROR (nm_dhcp_manager_error_quark ()) - -GQuark nm_dhcp_manager_error_quark (void); - - #define NM_TYPE_DHCP_MANAGER (nm_dhcp_manager_get_type ()) -#define NM_DHCP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManager)) -#define NM_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass)) +#define NM_DHCP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_MANAGER, NMDhcpManager)) +#define NM_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_MANAGER, NMDhcpManagerClass)) #define NM_IS_DHCP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_MANAGER)) #define NM_IS_DHCP_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_MANAGER)) -#define NM_DHCP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_MANAGER, NMDHCPManagerClass)) +#define NM_DHCP_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_MANAGER, NMDhcpManagerClass)) typedef struct { GObject parent; -} NMDHCPManager; +} NMDhcpManager; typedef struct { GObjectClass parent; -} NMDHCPManagerClass; +} NMDhcpManagerClass; GType nm_dhcp_manager_get_type (void); -NMDHCPManager *nm_dhcp_manager_get (void); +NMDhcpManager *nm_dhcp_manager_get (void); -void nm_dhcp_manager_set_default_hostname (NMDHCPManager *manager, +void nm_dhcp_manager_set_default_hostname (NMDhcpManager *manager, const char *hostname); -NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager, +NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager, const char *iface, + int ifindex, const GByteArray *hwaddr, const char *uuid, - guint priority, - NMSettingIP4Config *s_ip4, + guint32 priority, + gboolean send_hostname, + const char *dhcp_hostname, + const char *dhcp_client_id, guint32 timeout, - GByteArray *dhcp_anycast_addr); + const char *dhcp_anycast_addr, + const char *last_ip_address); -NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager, +NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, const char *iface, + int ifindex, const GByteArray *hwaddr, const char *uuid, - guint priority, - NMSettingIP6Config *s_ip6, + guint32 priority, + gboolean send_hostname, + const char *dhcp_hostname, guint32 timeout, - GByteArray *dhcp_anycast_addr, - gboolean info_only); + const char *dhcp_anycast_addr, + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy); -GSList * nm_dhcp_manager_get_lease_ip_configs (NMDHCPManager *self, +GSList * nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, const char *iface, const char *uuid, - gboolean ipv6); + gboolean ipv6, + guint32 default_route_metric); /* For testing only */ -NMIP4Config *nm_dhcp_manager_test_ip4_options_to_config (const char *dhcp_client, - const char *iface, - GHashTable *options, - const char *reason); - extern const char* nm_dhcp_helper_path; -#endif /* NM_DHCP_MANAGER_H */ +#endif /* __NETWORKMANAGER_DHCP_MANAGER_H__ */ diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c new file mode 100644 index 00000000..12dc03cc --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -0,0 +1,849 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-dhcp-systemd.h" +#include "nm-utils.h" +#include "nm-logging.h" +#include "nm-dhcp-utils.h" +#include "NetworkManagerUtils.h" +#include "gsystem-local-alloc.h" +#include "nm-platform.h" + +#include "nm-sd-adapt.h" + +#include "sd-dhcp-client.h" +#include "sd-dhcp6-client.h" +#include "dhcp-protocol.h" +#include "dhcp-lease-internal.h" +#include "dhcp6-protocol.h" +#include "dhcp6-lease-internal.h" + +G_DEFINE_TYPE (NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT) + +#define NM_DHCP_SYSTEMD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdPrivate)) + +typedef struct { + struct sd_dhcp_client *client4; + struct sd_dhcp6_client *client6; + char *lease_file; + + guint timeout_id; + guint request_count; + + gboolean privacy; +} NMDhcpSystemdPrivate; + +/************************************************************/ + +#define DHCP_OPTION_NIS_DOMAIN 40 +#define DHCP_OPTION_NIS_SERVERS 41 +#define DHCP_OPTION_DOMAIN_SEARCH 119 +#define DHCP_OPTION_RFC3442_ROUTES 121 +#define DHCP_OPTION_MS_ROUTES 249 +#define DHCP_OPTION_WPAD 252 + +/* Internal values */ +#define DHCP_OPTION_IP_ADDRESS 1024 +#define DHCP_OPTION_EXPIRY 1025 +#define DHCP6_OPTION_IP_ADDRESS 1026 +#define DHCP6_OPTION_PREFIXLEN 1027 +#define DHCP6_OPTION_PREFERRED_LIFE 1028 +#define DHCP6_OPTION_MAX_LIFE 1029 +#define DHCP6_OPTION_STARTS 1030 +#define DHCP6_OPTION_LIFE_STARTS 1031 +#define DHCP6_OPTION_RENEW 1032 +#define DHCP6_OPTION_REBIND 1033 +#define DHCP6_OPTION_IAID 1034 + +typedef struct { + guint num; + const char *name; + gboolean include; +} ReqOption; + +#define REQPREFIX "requested_" + +static const ReqOption dhcp4_requests[] = { + { DHCP_OPTION_SUBNET_MASK, REQPREFIX "subnet_mask", TRUE }, + { DHCP_OPTION_TIME_OFFSET, REQPREFIX "time_offset", TRUE }, + { DHCP_OPTION_ROUTER, REQPREFIX "routers", TRUE }, + { DHCP_OPTION_DOMAIN_NAME_SERVER, REQPREFIX "domain_name_servers", TRUE }, + { DHCP_OPTION_HOST_NAME, REQPREFIX "host_name", TRUE }, + { DHCP_OPTION_DOMAIN_NAME, REQPREFIX "domain_name", TRUE }, + { DHCP_OPTION_INTERFACE_MTU, REQPREFIX "interface_mtu", TRUE }, + { DHCP_OPTION_BROADCAST, REQPREFIX "broadcast_address", TRUE }, + { DHCP_OPTION_STATIC_ROUTE, REQPREFIX "static_routes", TRUE }, + { DHCP_OPTION_NIS_DOMAIN, REQPREFIX "nis_domain", TRUE }, + { DHCP_OPTION_NIS_SERVERS, REQPREFIX "nis_servers", TRUE }, + { DHCP_OPTION_NTP_SERVER, REQPREFIX "ntp_servers", TRUE }, + { DHCP_OPTION_SERVER_IDENTIFIER, REQPREFIX "dhcp_server_identifier", TRUE }, + { DHCP_OPTION_DOMAIN_SEARCH, REQPREFIX "domain_search", TRUE }, + { DHCP_OPTION_CLASSLESS_STATIC_ROUTE, REQPREFIX "rfc3442_classless_static_routes", TRUE }, + { DHCP_OPTION_MS_ROUTES, REQPREFIX "ms_classless_static_routes", TRUE }, + { DHCP_OPTION_WPAD, REQPREFIX "wpad", TRUE }, + + /* Internal values */ + { DHCP_OPTION_IP_ADDRESS_LEASE_TIME, REQPREFIX "expiry", FALSE }, + { DHCP_OPTION_CLIENT_IDENTIFIER, REQPREFIX "dhcp_client_identifier", FALSE }, + { DHCP_OPTION_IP_ADDRESS, REQPREFIX "ip_address", FALSE }, + { 0, NULL, FALSE } +}; + +static const ReqOption dhcp6_requests[] = { + { DHCP6_OPTION_CLIENTID, REQPREFIX "dhcp6_client_id", TRUE }, + + /* Don't request server ID by default; some servers don't reply to + * Information Requests that request the Server ID. + */ + { DHCP6_OPTION_SERVERID, REQPREFIX "dhcp6_server_id", FALSE }, + + { DHCP6_OPTION_DNS_SERVERS, REQPREFIX "dhcp6_name_servers", TRUE }, + { DHCP6_OPTION_DOMAIN_LIST, REQPREFIX "dhcp6_domain_search", TRUE }, + { DHCP6_OPTION_SNTP_SERVERS, REQPREFIX "dhcp6_sntp_servers", TRUE }, + + /* Internal values */ + { DHCP6_OPTION_IP_ADDRESS, REQPREFIX "ip6_address", FALSE }, + { DHCP6_OPTION_PREFIXLEN, REQPREFIX "ip6_prefixlen", FALSE }, + { DHCP6_OPTION_PREFERRED_LIFE, REQPREFIX "preferred_life", FALSE }, + { DHCP6_OPTION_MAX_LIFE, REQPREFIX "max_life", FALSE }, + { DHCP6_OPTION_STARTS, REQPREFIX "starts", FALSE }, + { DHCP6_OPTION_LIFE_STARTS, REQPREFIX "life_starts", FALSE }, + { DHCP6_OPTION_RENEW, REQPREFIX "renew", FALSE }, + { DHCP6_OPTION_REBIND, REQPREFIX "rebind", FALSE }, + { DHCP6_OPTION_IAID, REQPREFIX "iaid", FALSE }, + { 0, NULL, FALSE } +}; + +static void +take_option (GHashTable *options, + const ReqOption *requests, + guint option, + char *value) +{ + guint i; + + g_return_if_fail (value != NULL); + + for (i = 0; requests[i].name; i++) { + if (requests[i].num == option) { + g_hash_table_insert (options, + (gpointer) (requests[i].name + STRLEN (REQPREFIX)), + value); + break; + } + } + /* Option should always be found */ + g_assert (requests[i].name); +} + +static void +add_option (GHashTable *options, const ReqOption *requests, guint option, const char *value) +{ + if (options) + take_option (options, requests, option, g_strdup (value)); +} + +static void +add_option_u32 (GHashTable *options, const ReqOption *requests, guint option, guint32 value) +{ + if (options) + take_option (options, requests, option, g_strdup_printf ("%u", value)); +} + +static void +add_option_u64 (GHashTable *options, const ReqOption *requests, guint option, guint64 value) +{ + if (options) + take_option (options, requests, option, g_strdup_printf ("%" G_GUINT64_FORMAT, value)); +} + +static void +add_requests_to_options (GHashTable *options, const ReqOption *requests) +{ + guint i; + + for (i = 0; options && requests[i].name; i++) { + if (requests[i].include) + g_hash_table_insert (options, (gpointer) requests[i].name, g_strdup ("1")); + } +} + +#define LOG_LEASE(domain, ...) \ +G_STMT_START { \ + if (log_lease) { \ + nm_log (LOGL_INFO, (domain), __VA_ARGS__); \ + } \ +} G_STMT_END + +static NMIP4Config * +lease_to_ip4_config (sd_dhcp_lease *lease, + GHashTable *options, + guint32 default_priority, + gboolean log_lease, + GError **error) +{ + NMIP4Config *ip4_config = NULL; + struct in_addr tmp_addr; + const struct in_addr *addr_list; + char buf[INET_ADDRSTRLEN]; + const char *str; + guint32 lifetime = 0, i; + NMPlatformIP4Address address; + GString *l; + struct sd_dhcp_route *routes; + guint16 mtu; + int r, num; + guint64 end_time; + + g_return_val_if_fail (lease != NULL, NULL); + + ip4_config = nm_ip4_config_new (); + + /* Address */ + sd_dhcp_lease_get_address (lease, &tmp_addr); + memset (&address, 0, sizeof (address)); + address.address = tmp_addr.s_addr; + str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL); + LOG_LEASE (LOGD_DHCP4, " address %s", str); + add_option (options, dhcp4_requests, DHCP_OPTION_IP_ADDRESS, str); + + /* Prefix/netmask */ + sd_dhcp_lease_get_netmask (lease, &tmp_addr); + address.plen = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); + LOG_LEASE (LOGD_DHCP4, " plen %d", address.plen); + add_option (options, + dhcp4_requests, + DHCP_OPTION_SUBNET_MASK, + nm_utils_inet4_ntop (tmp_addr.s_addr, NULL)); + + /* Lease time */ + sd_dhcp_lease_get_lifetime (lease, &lifetime); + address.timestamp = nm_utils_get_monotonic_timestamp_s (); + address.lifetime = address.preferred = lifetime; + end_time = (guint64) time (NULL) + lifetime; + LOG_LEASE (LOGD_DHCP4, " expires in %" G_GUINT32_FORMAT " seconds", lifetime); + add_option_u64 (options, + dhcp4_requests, + DHCP_OPTION_IP_ADDRESS_LEASE_TIME, + end_time); + + address.source = NM_IP_CONFIG_SOURCE_DHCP; + nm_ip4_config_add_address (ip4_config, &address); + + /* Gateway */ + r = sd_dhcp_lease_get_router (lease, &tmp_addr); + if (r == 0) { + nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr); + str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL); + LOG_LEASE (LOGD_DHCP4, " gateway %s", str); + add_option (options, dhcp4_requests, DHCP_OPTION_ROUTER, str); + } + + /* DNS Servers */ + num = sd_dhcp_lease_get_dns (lease, &addr_list); + if (num > 0) { + l = g_string_sized_new (30); + for (i = 0; i < num; i++) { + if (addr_list[i].s_addr) { + nm_ip4_config_add_nameserver (ip4_config, addr_list[i].s_addr); + str = nm_utils_inet4_ntop (addr_list[i].s_addr, NULL); + LOG_LEASE (LOGD_DHCP4, " nameserver '%s'", str); + g_string_append_printf (l, "%s%s", l->len ? " " : "", str); + } + } + if (l->len) + add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME_SERVER, l->str); + g_string_free (l, TRUE); + } + + /* Domain Name */ + r = sd_dhcp_lease_get_domainname (lease, &str); + if (r == 0) { + /* Multiple domains sometimes stuffed into the option */ + char **domains = g_strsplit (str, " ", 0); + char **s; + + for (s = domains; *s; s++) { + LOG_LEASE (LOGD_DHCP4, " domain name '%s'", *s); + nm_ip4_config_add_domain (ip4_config, *s); + } + g_strfreev (domains); + add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME, str); + } + + /* Hostname */ + r = sd_dhcp_lease_get_hostname (lease, &str); + if (r == 0) { + LOG_LEASE (LOGD_DHCP4, " hostname '%s'", str); + add_option (options, dhcp4_requests, DHCP_OPTION_HOST_NAME, str); + } + + /* Routes */ + num = sd_dhcp_lease_get_routes (lease, &routes); + if (num > 0) { + l = g_string_sized_new (30); + for (i = 0; i < num; i++) { + NMPlatformIP4Route route; + const char *gw_str; + + memset (&route, 0, sizeof (route)); + route.network = routes[i].dst_addr.s_addr; + route.plen = routes[i].dst_prefixlen; + route.gateway = routes[i].gw_addr.s_addr; + route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.metric = default_priority; + nm_ip4_config_add_route (ip4_config, &route); + + str = nm_utils_inet4_ntop (route.network, buf); + gw_str = nm_utils_inet4_ntop (route.gateway, NULL); + LOG_LEASE (LOGD_DHCP4, " static route %s/%d gw %s", str, route.plen, gw_str); + + g_string_append_printf (l, "%s%s/%d %s", l->len ? " " : "", str, route.plen, gw_str); + } + add_option (options, dhcp4_requests, DHCP_OPTION_RFC3442_ROUTES, l->str); + g_string_free (l, TRUE); + } + + /* MTU */ + r = sd_dhcp_lease_get_mtu (lease, &mtu); + if (r == 0 && mtu) { + nm_ip4_config_set_mtu (ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP); + add_option_u32 (options, dhcp4_requests, DHCP_OPTION_INTERFACE_MTU, mtu); + LOG_LEASE (LOGD_DHCP4, " mtu %u", mtu); + } + + /* NTP servers */ + num = sd_dhcp_lease_get_ntp (lease, &addr_list); + if (num > 0) { + l = g_string_sized_new (30); + for (i = 0; i < num; i++) { + str = nm_utils_inet4_ntop (addr_list[i].s_addr, buf); + LOG_LEASE (LOGD_DHCP4, " ntp server '%s'", str); + g_string_append_printf (l, "%s%s", l->len ? " " : "", str); + } + add_option (options, dhcp4_requests, DHCP_OPTION_NTP_SERVER, l->str); + g_string_free (l, TRUE); + } + + return ip4_config; +} + +/************************************************************/ + +static char * +get_leasefile_path (const char *iface, const char *uuid, gboolean ipv6) +{ + return g_strdup_printf (NMSTATEDIR "/internal%s-%s-%s.lease", + ipv6 ? "6" : "", + uuid, + iface); +} + +static GSList * +nm_dhcp_systemd_get_lease_ip_configs (const char *iface, + const char *uuid, + gboolean ipv6, + guint32 default_route_metric) +{ + GSList *leases = NULL; + gs_free char *path = NULL; + sd_dhcp_lease *lease = NULL; + NMIP4Config *ip4_config; + int r; + + if (ipv6) + return NULL; + + path = get_leasefile_path (iface, uuid, FALSE); + r = sd_dhcp_lease_load (&lease, path); + if (r == 0 && lease) { + ip4_config = lease_to_ip4_config (lease, NULL, default_route_metric, FALSE, NULL); + if (ip4_config) + leases = g_slist_append (leases, ip4_config); + } + + return leases; +} + +/************************************************************/ + +static void +_save_client_id (NMDhcpSystemd *self, + uint8_t type, + const uint8_t *client_id, + size_t len) +{ + gs_unref_bytes GBytes *b = NULL; + gs_free char *buf = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (client_id != NULL); + g_return_if_fail (len > 0); + + if (!nm_dhcp_client_get_client_id (NM_DHCP_CLIENT (self))) { + buf = g_malloc (len + 1); + buf[0] = type; + memcpy (buf + 1, client_id, len); + b = g_bytes_new (buf, len + 1); + nm_dhcp_client_set_client_id (NM_DHCP_CLIENT (self), b); + } +} + +static void +bound4_handle (NMDhcpSystemd *self) +{ + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); + const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); + sd_dhcp_lease *lease; + NMIP4Config *ip4_config; + GHashTable *options; + GError *error = NULL; + int r; + + nm_log_dbg (LOGD_DHCP4, "(%s): lease available", iface); + + r = sd_dhcp_client_get_lease (priv->client4, &lease); + if (r < 0 || !lease) { + nm_log_warn (LOGD_DHCP4, "(%s): no lease!", iface); + nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); + return; + } + + options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); + ip4_config = lease_to_ip4_config (lease, + options, + nm_dhcp_client_get_priority (NM_DHCP_CLIENT (self)), + TRUE, + &error); + if (ip4_config) { + const uint8_t *client_id = NULL; + size_t client_id_len = 0; + uint8_t type = 0; + + add_requests_to_options (options, dhcp4_requests); + sd_dhcp_lease_save (lease, priv->lease_file); + + sd_dhcp_client_get_client_id(priv->client4, &type, &client_id, &client_id_len); + if (client_id) + _save_client_id (self, type, client_id, client_id_len); + + nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), + NM_DHCP_STATE_BOUND, + G_OBJECT (ip4_config), + options); + } else { + nm_log_warn (LOGD_DHCP4, "(%s): %s", iface, error->message); + nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); + g_clear_error (&error); + } + + sd_dhcp_lease_unref (lease); + g_hash_table_destroy (options); + g_clear_object (&ip4_config); +} + +static void +dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data) +{ + NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data); + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); + const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); + + g_assert (priv->client4 == client); + + nm_log_dbg (LOGD_DHCP4, "(%s): DHCPv4 client event %d", iface, event); + + switch (event) { + case DHCP_EVENT_EXPIRED: + nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_EXPIRE, NULL, NULL); + break; + case DHCP_EVENT_STOP: + nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL); + break; + case DHCP_EVENT_RENEW: + case DHCP_EVENT_IP_CHANGE: + case DHCP_EVENT_IP_ACQUIRE: + bound4_handle (self); + break; + default: + nm_log_warn (LOGD_DHCP4, "(%s): unhandled DHCP event %d", iface, event); + break; + } +} + +static guint16 +get_arp_type (const GByteArray *hwaddr) +{ + if (hwaddr->len == ETH_ALEN) + return ARPHRD_ETHER; + else if (hwaddr->len == INFINIBAND_ALEN) + return ARPHRD_INFINIBAND; + else + g_assert_not_reached (); +} + +static gboolean +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) +{ + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client); + const char *iface = nm_dhcp_client_get_iface (client); + const GByteArray *hwaddr; + sd_dhcp_lease *lease = NULL; + GBytes *override_client_id; + const uint8_t *client_id = NULL; + size_t client_id_len = 0; + struct in_addr last_addr = { 0 }; + const char *hostname; + int r, i; + + g_assert (priv->client4 == NULL); + g_assert (priv->client6 == NULL); + + g_free (priv->lease_file); + priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), FALSE); + + r = sd_dhcp_client_new (&priv->client4); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to create DHCPv4 client (%d)", iface, r); + return FALSE; + } + + r = sd_dhcp_client_attach_event (priv->client4, NULL, 0); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to attach DHCP event (%d)", iface, r); + goto error; + } + + hwaddr = nm_dhcp_client_get_hw_addr (client); + if (hwaddr) { + r = sd_dhcp_client_set_mac (priv->client4, + hwaddr->data, + hwaddr->len, + get_arp_type (hwaddr)); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP MAC address (%d)", iface, r); + goto error; + } + } + + r = sd_dhcp_client_set_index (priv->client4, nm_dhcp_client_get_ifindex (client)); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP ifindex (%d)", iface, r); + goto error; + } + + r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP callback (%d)", iface, r); + goto error; + } + + r = sd_dhcp_client_set_request_broadcast (priv->client4, true); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP broadcast (%d)", iface, r); + goto error; + } + + sd_dhcp_lease_load (&lease, priv->lease_file); + + if (last_ip4_address) + inet_pton (AF_INET, last_ip4_address, &last_addr); + else if (lease) + sd_dhcp_lease_get_address (lease, &last_addr); + + if (last_addr.s_addr) { + r = sd_dhcp_client_set_request_address (priv->client4, &last_addr); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set last IPv4 address (%d)", iface, r); + goto error; + } + } + + override_client_id = nm_dhcp_client_get_client_id (client); + if (override_client_id) { + client_id = g_bytes_get_data (override_client_id, &client_id_len); + g_assert (client_id && client_id_len); + sd_dhcp_client_set_client_id (priv->client4, + client_id[0], + client_id + 1, + client_id_len - 1); + } else if (lease) { + r = sd_dhcp_lease_get_client_id (lease, &client_id, &client_id_len); + if (r == 0 && client_id_len) { + sd_dhcp_client_set_client_id (priv->client4, + client_id[0], + client_id + 1, + client_id_len - 1); + _save_client_id (NM_DHCP_SYSTEMD (client), + client_id[0], + client_id + 1, + client_id_len - 1); + } + } + + if (lease) + sd_dhcp_lease_unref (lease); + + /* Add requested options */ + for (i = 0; dhcp4_requests[i].name; i++) { + if (dhcp4_requests[i].include) + sd_dhcp_client_set_request_option (priv->client4, dhcp4_requests[i].num); + } + + hostname = nm_dhcp_client_get_hostname (client); + if (hostname) { + r = sd_dhcp_client_set_hostname (priv->client4, hostname); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to set DHCP hostname (%d)", iface, r); + goto error; + } + } + + r = sd_dhcp_client_start (priv->client4); + if (r < 0) { + nm_log_warn (LOGD_DHCP4, "(%s): failed to start DHCP (%d)", iface, r); + goto error; + } + + return TRUE; + +error: + sd_dhcp_client_unref (priv->client4); + priv->client4 = NULL; + return FALSE; +} + +static void +bound6_handle (NMDhcpSystemd *self) +{ + /* not yet supported... */ + nm_log_warn (LOGD_DHCP6, "(%s): internal DHCP does not yet support DHCPv6", + nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self))); + nm_dhcp_client_set_state (NM_DHCP_CLIENT (self), NM_DHCP_STATE_FAIL, NULL, NULL); +} + +static void +dhcp6_event_cb (sd_dhcp6_client *client, int event, gpointer user_data) +{ + NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data); + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); + const char *iface = nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)); + + g_assert (priv->client6 == client); + + nm_log_dbg (LOGD_DHCP6, "(%s): DHCPv6 client event %d", iface, event); + + switch (event) { + case DHCP6_EVENT_RETRANS_MAX: + nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_TIMEOUT, NULL, NULL); + break; + case DHCP6_EVENT_RESEND_EXPIRE: + case DHCP6_EVENT_STOP: + nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL); + break; + case DHCP6_EVENT_IP_ACQUIRE: + bound6_handle (self); + break; + default: + nm_log_warn (LOGD_DHCP6, "(%s): unhandled DHCPv6 event %d", iface, event); + break; + } +} + +static gboolean +ip6_start (NMDhcpClient *client, + const char *dhcp_anycast_addr, + gboolean info_only, + NMSettingIP6ConfigPrivacy privacy, + const GByteArray *duid) +{ + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client); + const char *iface = nm_dhcp_client_get_iface (client); + const GByteArray *hwaddr; + int r, i; + + g_assert (priv->client4 == NULL); + g_assert (priv->client6 == NULL); + g_return_val_if_fail (duid != NULL, FALSE); + + g_free (priv->lease_file); + priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), TRUE); + + r = sd_dhcp6_client_new (&priv->client6); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to create DHCPv6 client (%d)", iface, r); + return FALSE; + } + + /* NM stores the entire DUID which includes the uint16 "type", while systemd + * wants the type passed separately from the following data. + */ + r = sd_dhcp6_client_set_duid (priv->client6, + ntohs (((const guint16 *) duid->data)[0]), + duid->data + 2, + duid->len - 2); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to create DHCPv6 client (%d)", iface, r); + return FALSE; + } + + r = sd_dhcp6_client_attach_event (priv->client6, NULL, 0); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to attach DHCP event (%d)", iface, r); + goto error; + } + + hwaddr = nm_dhcp_client_get_hw_addr (client); + if (hwaddr) { + r = sd_dhcp6_client_set_mac (priv->client6, + hwaddr->data, + hwaddr->len, + get_arp_type (hwaddr)); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to set DHCP MAC address (%d)", iface, r); + goto error; + } + } + + r = sd_dhcp6_client_set_index (priv->client6, nm_dhcp_client_get_ifindex (client)); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to set DHCP ifindex (%d)", iface, r); + goto error; + } + + r = sd_dhcp6_client_set_ifname (priv->client6, iface); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to set DHCP ifname (%d)", iface, r); + goto error; + } + + r = sd_dhcp6_client_set_callback (priv->client6, dhcp6_event_cb, client); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to set DHCP callback (%d)", iface, r); + goto error; + } + + /* Add requested options */ + for (i = 0; dhcp6_requests[i].name; i++) { + if (dhcp6_requests[i].include) + sd_dhcp6_client_set_request_option (priv->client6, dhcp6_requests[i].num); + } + + r = sd_dhcp6_client_start (priv->client6); + if (r < 0) { + nm_log_warn (LOGD_DHCP6, "(%s): failed to start DHCP (%d)", iface, r); + goto error; + } + + return TRUE; + +error: + sd_dhcp6_client_unref (priv->client6); + priv->client6 = NULL; + return FALSE; +} + +static void +stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) +{ + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (client); + int r = 0; + + if (priv->client4) + r = sd_dhcp_client_stop (priv->client4); + else if (priv->client6) + r = sd_dhcp6_client_stop (priv->client6); + + if (r) { + nm_log_warn (priv->client6 ? LOGD_DHCP6 : LOGD_DHCP4, + "(%s): failed to stop DHCP client (%d)", + nm_dhcp_client_get_iface (client), + r); + } +} + +/***************************************************/ + +static void +nm_dhcp_systemd_init (NMDhcpSystemd *self) +{ +} + +static void +dispose (GObject *object) +{ + NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (object); + + g_clear_pointer (&priv->lease_file, g_free); + + if (priv->client4) { + sd_dhcp_client_stop (priv->client4); + sd_dhcp_client_unref (priv->client4); + priv->client4 = NULL; + } + + if (priv->client6) { + sd_dhcp6_client_stop (priv->client6); + sd_dhcp6_client_unref (priv->client6); + priv->client6 = NULL; + } + + G_OBJECT_CLASS (nm_dhcp_systemd_parent_class)->dispose (object); +} + +static void +nm_dhcp_systemd_class_init (NMDhcpSystemdClass *sdhcp_class) +{ + NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS (sdhcp_class); + GObjectClass *object_class = G_OBJECT_CLASS (sdhcp_class); + + g_type_class_add_private (sdhcp_class, sizeof (NMDhcpSystemdPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + + client_class->ip4_start = ip4_start; + client_class->ip6_start = ip6_start; + client_class->stop = stop; +} + +static void __attribute__((constructor)) +register_dhcp_dhclient (void) +{ + g_type_init (); + _nm_dhcp_client_register (NM_TYPE_DHCP_SYSTEMD, + "internal", + NULL, + nm_dhcp_systemd_get_lease_ip_configs); +} + diff --git a/src/dhcp-manager/nm-dhcp-systemd.h b/src/dhcp-manager/nm-dhcp-systemd.h new file mode 100644 index 00000000..2a7a463e --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-systemd.h @@ -0,0 +1,45 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef NM_DHCP_SYSTEMD_H +#define NM_DHCP_SYSTEMD_H + +#include +#include + +#include "nm-dhcp-client.h" + +#define NM_TYPE_DHCP_SYSTEMD (nm_dhcp_systemd_get_type ()) +#define NM_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemd)) +#define NM_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) +#define NM_IS_DHCP_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP_SYSTEMD)) +#define NM_IS_DHCP_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP_SYSTEMD)) +#define NM_DHCP_SYSTEMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_SYSTEMD, NMDhcpSystemdClass)) + +typedef struct { + NMDhcpClient parent; +} NMDhcpSystemd; + +typedef struct { + NMDhcpClientClass parent; +} NMDhcpSystemdClass; + +GType nm_dhcp_systemd_get_type (void); + +#endif /* NM_DHCP_SYSTEMD_H */ + diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c new file mode 100644 index 00000000..5aa25ff0 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -0,0 +1,732 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2010 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "nm-logging.h" +#include "nm-dhcp-utils.h" +#include "nm-utils.h" +#include "NetworkManagerUtils.h" +#include "nm-platform.h" + +/********************************************/ + +static gboolean +ip4_process_dhcpcd_rfc3442_routes (const char *str, + guint32 priority, + NMIP4Config *ip4_config, + guint32 *gwaddr) +{ + char **routes, **r; + gboolean have_routes = FALSE; + + routes = g_strsplit (str, " ", 0); + if (g_strv_length (routes) == 0) + goto out; + + if ((g_strv_length (routes) % 2) != 0) { + nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid"); + goto out; + } + + for (r = routes; *r; r += 2) { + char *slash; + NMPlatformIP4Route route; + int rt_cidr = 32; + guint32 rt_addr, rt_route; + + slash = strchr(*r, '/'); + if (slash) { + *slash = '\0'; + errno = 0; + rt_cidr = strtol (slash + 1, NULL, 10); + if ((errno == EINVAL) || (errno == ERANGE)) { + nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1); + continue; + } + } + if (inet_pton (AF_INET, *r, &rt_addr) <= 0) { + nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r); + continue; + } + if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) { + nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1)); + continue; + } + + have_routes = TRUE; + if (rt_cidr == 0 && rt_addr == 0) { + /* FIXME: how to handle multiple routers? */ + *gwaddr = rt_route; + } else { + nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1)); + memset (&route, 0, sizeof (route)); + route.network = rt_addr; + route.plen = rt_cidr; + route.gateway = rt_route; + route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.metric = priority; + nm_ip4_config_add_route (ip4_config, &route); + } + } + +out: + g_strfreev (routes); + return have_routes; +} + +static const char ** +process_dhclient_rfc3442_route (const char **octets, + NMPlatformIP4Route *route, + gboolean *success) +{ + const char **o = octets; + int addr_len = 0, i = 0; + long int tmp; + char *next_hop; + guint32 tmp_addr; + + *success = FALSE; + + if (!*o) + return o; /* no prefix */ + + tmp = strtol (*o, NULL, 10); + if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */ + return o; + + memset (route, 0, sizeof (*route)); + route->plen = tmp; + o++; + + if (tmp > 0) + addr_len = ((tmp - 1) / 8) + 1; + + /* ensure there's at least the address + next hop left */ + if (g_strv_length ((char **) o) < addr_len + 4) + goto error; + + if (tmp) { + const char *addr[4] = { "0", "0", "0", "0" }; + char *str_addr; + + for (i = 0; i < addr_len; i++) + addr[i] = *o++; + + str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL); + if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) { + g_free (str_addr); + goto error; + } + tmp_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp); + route->network = tmp_addr; + } + + /* Handle next hop */ + next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL); + if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) { + g_free (next_hop); + goto error; + } + route->gateway = tmp_addr; + g_free (next_hop); + + *success = TRUE; + return o + 4; /* advance to past the next hop */ + +error: + return o; +} + +static gboolean +ip4_process_dhclient_rfc3442_routes (const char *str, + guint32 priority, + NMIP4Config *ip4_config, + guint32 *gwaddr) +{ + char **octets, **o; + gboolean have_routes = FALSE; + NMPlatformIP4Route route; + gboolean success; + + o = octets = g_strsplit_set (str, " .", 0); + if (g_strv_length (octets) < 5) { + nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); + goto out; + } + + while (*o) { + memset (&route, 0, sizeof (route)); + o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route, &success); + if (!success) { + nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes"); + break; + } + + have_routes = TRUE; + if (!route.plen) { + /* gateway passed as classless static route */ + *gwaddr = route.gateway; + } else { + char addr[INET_ADDRSTRLEN]; + + /* normal route */ + route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.metric = priority; + nm_ip4_config_add_route (ip4_config, &route); + + nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", + nm_utils_inet4_ntop (route.network, addr), route.plen, + nm_utils_inet4_ntop (route.gateway, NULL)); + } + } + +out: + g_strfreev (octets); + return have_routes; +} + +static gboolean +ip4_process_classless_routes (GHashTable *options, + guint32 priority, + NMIP4Config *ip4_config, + guint32 *gwaddr) +{ + const char *str, *p; + + g_return_val_if_fail (options != NULL, FALSE); + g_return_val_if_fail (ip4_config != NULL, FALSE); + + *gwaddr = 0; + + /* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a + * slightly different format: + * + * option classless-static-routes = array of (destination-descriptor ip-address); + * + * which results in: + * + * 0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6 + * + * dhcpcd supports classless static routes natively and uses this same + * option identifier with the following format: + * + * 192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41 + */ + str = g_hash_table_lookup (options, "classless_static_routes"); + + /* dhclient doesn't have actual support for rfc3442 classless static routes + * upstream. Thus, people resort to defining the option in dhclient.conf + * and using arbitrary formats like so: + * + * option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; + * + * See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html + */ + if (!str) + str = g_hash_table_lookup (options, "rfc3442_classless_static_routes"); + + /* Microsoft version; same as rfc3442 but with a different option # (249) */ + if (!str) + str = g_hash_table_lookup (options, "ms_classless_static_routes"); + + if (!str || !strlen (str)) + return FALSE; + + p = str; + while (*p) { + if (!g_ascii_isdigit (*p) && (*p != ' ') && (*p != '.') && (*p != '/')) { + nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str); + return FALSE; + } + p++; + }; + + if (strchr (str, '/')) { + /* dhcpcd format */ + return ip4_process_dhcpcd_rfc3442_routes (str, priority, ip4_config, gwaddr); + } + + return ip4_process_dhclient_rfc3442_routes (str, priority, ip4_config, gwaddr); +} + +static void +process_classful_routes (GHashTable *options, guint32 priority, NMIP4Config *ip4_config) +{ + const char *str; + char **searches, **s; + + str = g_hash_table_lookup (options, "static_routes"); + if (!str) + return; + + searches = g_strsplit (str, " ", 0); + if ((g_strv_length (searches) % 2)) { + nm_log_info (LOGD_DHCP, " static routes provided, but invalid"); + goto out; + } + + for (s = searches; *s; s += 2) { + NMPlatformIP4Route route; + guint32 rt_addr, rt_route; + + if (inet_pton (AF_INET, *s, &rt_addr) <= 0) { + nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route address: '%s'", *s); + continue; + } + if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) { + nm_log_warn (LOGD_DHCP, "DHCP provided invalid static route gateway: '%s'", *(s + 1)); + continue; + } + + // FIXME: ensure the IP address and route are sane + + memset (&route, 0, sizeof (route)); + route.network = rt_addr; + /* RFC 2132, updated by RFC 3442: + The Static Routes option (option 33) does not provide a subnet mask + for each route - it is assumed that the subnet mask is implicit in + whatever network number is specified in each route entry */ + route.plen = nm_utils_ip4_get_default_prefix (rt_addr); + if (rt_addr & ~nm_utils_ip4_prefix_to_netmask (route.plen)) { + /* RFC 943: target not "this network"; using host routing */ + route.plen = 32; + } + route.gateway = rt_route; + route.source = NM_IP_CONFIG_SOURCE_DHCP; + route.metric = priority; + + nm_ip4_config_add_route (ip4_config, &route); + nm_log_info (LOGD_DHCP, " static route %s", + nm_platform_ip4_route_to_string (&route)); + } + +out: + g_strfreev (searches); +} + +static void +process_domain_search (const char *str, GFunc add_func, gpointer user_data) +{ + char **searches, **s; + char *unescaped, *p; + int i; + + g_return_if_fail (str != NULL); + g_return_if_fail (add_func != NULL); + + p = unescaped = g_strdup (str); + do { + p = strstr (p, "\\032"); + if (!p) + break; + + /* Clear the escaped space with real spaces */ + for (i = 0; i < 4; i++) + *p++ = ' '; + } while (*p++); + + if (strchr (unescaped, '\\')) { + nm_log_warn (LOGD_DHCP, " invalid domain search: '%s'", unescaped); + goto out; + } + + searches = g_strsplit (unescaped, " ", 0); + for (s = searches; *s; s++) { + if (strlen (*s)) { + nm_log_info (LOGD_DHCP, " domain search '%s'", *s); + add_func (*s, user_data); + } + } + g_strfreev (searches); + +out: + g_free (unescaped); +} + +static void +ip4_add_domain_search (gpointer data, gpointer user_data) +{ + nm_ip4_config_add_search (NM_IP4_CONFIG (user_data), (const char *) data); +} + +NMIP4Config * +nm_dhcp_utils_ip4_config_from_options (const char *iface, + GHashTable *options, + guint32 priority) +{ + NMIP4Config *ip4_config = NULL; + guint32 tmp_addr; + NMPlatformIP4Address address; + char *str = NULL; + guint32 gwaddr = 0, plen = 0; + + g_return_val_if_fail (options != NULL, NULL); + + ip4_config = nm_ip4_config_new (); + memset (&address, 0, sizeof (address)); + address.timestamp = nm_utils_get_monotonic_timestamp_s (); + + str = g_hash_table_lookup (options, "ip_address"); + if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { + address.address = tmp_addr; + nm_log_info (LOGD_DHCP4, " address %s", str); + } else + goto error; + + str = g_hash_table_lookup (options, "subnet_mask"); + if (str && (inet_pton (AF_INET, str, &tmp_addr) > 0)) { + plen = nm_utils_ip4_netmask_to_prefix (tmp_addr); + nm_log_info (LOGD_DHCP4, " plen %d (%s)", plen, str); + } else { + /* Get default netmask for the IP according to appropriate class. */ + plen = nm_utils_ip4_get_default_prefix (address.address); + nm_log_info (LOGD_DHCP4, " plen %d (default)", plen); + } + address.plen = plen; + + /* Routes: if the server returns classless static routes, we MUST ignore + * the 'static_routes' option. + */ + if (!ip4_process_classless_routes (options, priority, ip4_config, &gwaddr)) + process_classful_routes (options, priority, ip4_config); + + if (gwaddr) { + nm_log_info (LOGD_DHCP4, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL)); + nm_ip4_config_set_gateway (ip4_config, gwaddr); + } else { + /* If the gateway wasn't provided as a classless static route with a + * subnet length of 0, try to find it using the old-style 'routers' option. + */ + str = g_hash_table_lookup (options, "routers"); + if (str) { + char **routers = g_strsplit (str, " ", 0); + char **s; + + for (s = routers; *s; s++) { + /* FIXME: how to handle multiple routers? */ + if (inet_pton (AF_INET, *s, &gwaddr) > 0) { + nm_ip4_config_set_gateway (ip4_config, gwaddr); + nm_log_info (LOGD_DHCP4, " gateway %s", *s); + break; + } else + nm_log_warn (LOGD_DHCP4, "ignoring invalid gateway '%s'", *s); + } + g_strfreev (routers); + } + } + + /* + * RFC 2132, section 9.7 + * DHCP clients use the contents of the 'server identifier' field + * as the destination address for any DHCP messages unicast to + * the DHCP server. + * + * Some ISP's provide leases from central servers that are on + * different subnets that the address offered. If the host + * does not configure the interface as the default route, the + * dhcp server may not be reachable via unicast, and a host + * specific route is needed. + **/ + str = g_hash_table_lookup (options, "dhcp_server_identifier"); + if (str) { + if (inet_pton (AF_INET, str, &tmp_addr) > 0) { + + nm_log_info (LOGD_DHCP4, " server identifier %s", str); + if ( nm_utils_ip4_address_clear_host_address(tmp_addr, address.plen) != nm_utils_ip4_address_clear_host_address(address.address, address.plen) + && !nm_ip4_config_get_direct_route_for_host (ip4_config, tmp_addr)) { + /* DHCP server not on assigned subnet and the no direct route was returned. Add route */ + NMPlatformIP4Route route = { 0 }; + + route.network = tmp_addr; + route.plen = 32; + /* this will be a device route if gwaddr is 0 */ + route.gateway = gwaddr; + route.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", + nm_platform_ip4_route_to_string (&route)); + } + } + else + nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str); + } + + str = g_hash_table_lookup (options, "dhcp_lease_time"); + if (str) { + address.lifetime = address.preferred = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP4, " lease time %d", address.lifetime); + } + + address.source = NM_IP_CONFIG_SOURCE_DHCP; + nm_ip4_config_add_address (ip4_config, &address); + + str = g_hash_table_lookup (options, "host_name"); + if (str) + nm_log_info (LOGD_DHCP4, " hostname '%s'", str); + + str = g_hash_table_lookup (options, "domain_name_servers"); + if (str) { + char **dns = g_strsplit (str, " ", 0); + char **s; + + for (s = dns; *s; s++) { + if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { + if (tmp_addr) { + nm_ip4_config_add_nameserver (ip4_config, tmp_addr); + nm_log_info (LOGD_DHCP4, " nameserver '%s'", *s); + } + } else + nm_log_warn (LOGD_DHCP4, "ignoring invalid nameserver '%s'", *s); + } + g_strfreev (dns); + } + + str = g_hash_table_lookup (options, "domain_name"); + if (str) { + char **domains = g_strsplit (str, " ", 0); + char **s; + + for (s = domains; *s; s++) { + nm_log_info (LOGD_DHCP4, " domain name '%s'", *s); + nm_ip4_config_add_domain (ip4_config, *s); + } + g_strfreev (domains); + } + + str = g_hash_table_lookup (options, "domain_search"); + if (str) + process_domain_search (str, ip4_add_domain_search, ip4_config); + + str = g_hash_table_lookup (options, "netbios_name_servers"); + if (str) { + char **nbns = g_strsplit (str, " ", 0); + char **s; + + for (s = nbns; *s; s++) { + if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { + if (tmp_addr) { + nm_ip4_config_add_wins (ip4_config, tmp_addr); + nm_log_info (LOGD_DHCP4, " wins '%s'", *s); + } + } else + nm_log_warn (LOGD_DHCP4, "ignoring invalid WINS server '%s'", *s); + } + g_strfreev (nbns); + } + + str = g_hash_table_lookup (options, "interface_mtu"); + if (str) { + int int_mtu; + + errno = 0; + int_mtu = strtol (str, NULL, 10); + if ((errno == EINVAL) || (errno == ERANGE)) + goto error; + + if (int_mtu > 576) + nm_ip4_config_set_mtu (ip4_config, int_mtu, NM_IP_CONFIG_SOURCE_DHCP); + } + + str = g_hash_table_lookup (options, "nis_domain"); + if (str) { + nm_log_info (LOGD_DHCP4, " NIS domain '%s'", str); + nm_ip4_config_set_nis_domain (ip4_config, str); + } + + str = g_hash_table_lookup (options, "nis_servers"); + if (str) { + char **nis = g_strsplit (str, " ", 0); + char **s; + + for (s = nis; *s; s++) { + if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { + if (tmp_addr) { + nm_ip4_config_add_nis_server (ip4_config, tmp_addr); + nm_log_info (LOGD_DHCP4, " nis '%s'", *s); + } + } else + nm_log_warn (LOGD_DHCP4, "ignoring invalid NIS server '%s'", *s); + } + g_strfreev (nis); + } + + return ip4_config; + +error: + g_object_unref (ip4_config); + return NULL; +} + +/********************************************/ + +static void +ip6_add_domain_search (gpointer data, gpointer user_data) +{ + nm_ip6_config_add_search (NM_IP6_CONFIG (user_data), (const char *) data); +} + +NMIP6Config * +nm_dhcp_utils_ip6_config_from_options (const char *iface, + GHashTable *options, + guint32 priority, + gboolean info_only) +{ + NMIP6Config *ip6_config = NULL; + struct in6_addr tmp_addr; + NMPlatformIP6Address address; + char *str = NULL; + GHashTableIter iter; + gpointer key, value; + + g_return_val_if_fail (options != NULL, NULL); + + memset (&address, 0, sizeof (address)); + address.plen = 128; + address.timestamp = nm_utils_get_monotonic_timestamp_s (); + + g_hash_table_iter_init (&iter, options); + while (g_hash_table_iter_next (&iter, &key, &value)) { + nm_log_dbg (LOGD_DHCP6, "(%s): option '%s'=>'%s'", + iface, (const char *) key, (const char *) value); + } + + ip6_config = nm_ip6_config_new (); + + str = g_hash_table_lookup (options, "max_life"); + if (str) { + address.lifetime = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP6, " valid_lft %d", address.lifetime); + } + + str = g_hash_table_lookup (options, "preferred_life"); + if (str) { + address.preferred = strtoul (str, NULL, 10); + nm_log_info (LOGD_DHCP6, " preferred_lft %d", address.preferred); + } + + str = g_hash_table_lookup (options, "ip6_address"); + if (str) { + if (!inet_pton (AF_INET6, str, &tmp_addr)) { + nm_log_warn (LOGD_DHCP6, "(%s): DHCP returned invalid address '%s'", + iface, str); + goto error; + } + + address.address = tmp_addr; + address.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) { + /* No address in Managed mode is a hard error */ + goto error; + } + + str = g_hash_table_lookup (options, "host_name"); + if (str) + nm_log_info (LOGD_DHCP6, " hostname '%s'", str); + + str = g_hash_table_lookup (options, "dhcp6_name_servers"); + if (str) { + char **dns = g_strsplit (str, " ", 0); + char **s; + + for (s = dns; *s; s++) { + if (inet_pton (AF_INET6, *s, &tmp_addr) > 0) { + if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_addr)) { + nm_ip6_config_add_nameserver (ip6_config, &tmp_addr); + nm_log_info (LOGD_DHCP6, " nameserver '%s'", *s); + } + } else + nm_log_warn (LOGD_DHCP6, "ignoring invalid nameserver '%s'", *s); + } + g_strfreev (dns); + } + + str = g_hash_table_lookup (options, "dhcp6_domain_search"); + if (str) + process_domain_search (str, ip6_add_domain_search, ip6_config); + + return ip6_config; + +error: + g_object_unref (ip6_config); + return NULL; +} + +char * +nm_dhcp_utils_duid_to_string (const GByteArray *duid) +{ + guint32 i = 0; + GString *s; + + g_return_val_if_fail (duid != NULL, NULL); + + s = g_string_sized_new (MIN (duid->len * 3, 50)); + while (i < duid->len) { + if (s->len) + g_string_append_c (s, ':'); + g_string_append_printf (s, "%02x", duid->data[i++]); + } + return g_string_free (s, FALSE); +} + +/** + * nm_dhcp_utils_client_id_string_to_bytes: + * @client_id: the client ID string + * + * Accepts either a hex string ("aa:bb:cc") representing a binary client ID + * (the first byte is assumed to be the 'type' field per RFC 2132 section 9.14), + * or a string representing a non-hardware-address client ID, in which case + * the 'type' field is set to 0. + * + * Returns: the binary client ID suitable for sending over the wire + * to the DHCP server. + */ +GBytes * +nm_dhcp_utils_client_id_string_to_bytes (const char *client_id) +{ + GBytes *bytes = NULL; + guint len; + char *c; + + g_return_val_if_fail (client_id && client_id[0], NULL); + + /* Try as hex encoded */ + if (strchr (client_id, ':')) + bytes = nm_utils_hexstr2bin (client_id); + if (!bytes) { + /* Fall back to string */ + len = strlen (client_id); + c = g_malloc (len + 1); + c[0] = 0; /* type: non-hardware address per RFC 2132 section 9.14 */ + memcpy (c + 1, client_id, len); + bytes = g_bytes_new_take (c, len + 1); + } + + return bytes; +} + diff --git a/src/dhcp-manager/nm-dhcp-utils.h b/src/dhcp-manager/nm-dhcp-utils.h new file mode 100644 index 00000000..a01cf4c2 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-utils.h @@ -0,0 +1,41 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DHCP_UTILS_H__ +#define __NETWORKMANAGER_DHCP_UTILS_H__ + +#include +#include +#include +#include + +NMIP4Config *nm_dhcp_utils_ip4_config_from_options (const char *iface, + GHashTable *options, + guint priority); + +NMIP6Config *nm_dhcp_utils_ip6_config_from_options (const char *iface, + GHashTable *options, + guint priority, + gboolean info_only); + +char * nm_dhcp_utils_duid_to_string (const GByteArray *duid); + +GBytes * nm_dhcp_utils_client_id_string_to_bytes (const char *client_id); + +#endif /* __NETWORKMANAGER_DHCP_UTILS_H__ */ + diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c new file mode 100644 index 00000000..a6d81727 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c @@ -0,0 +1,209 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include "sd-event.h" +#include "time-util.h" + +struct sd_event_source { + guint refcount; + guint id; + gpointer user_data; + + GIOChannel *channel; + sd_event_io_handler_t io_cb; + + uint64_t usec; + sd_event_time_handler_t time_cb; +}; + +int +sd_event_source_set_priority (sd_event_source *s, int64_t priority) +{ + return 0; +} + +sd_event_source* +sd_event_source_unref (sd_event_source *s) +{ + + if (!s) + return NULL; + + g_return_val_if_fail (s->refcount, NULL); + + s->refcount--; + if (s->refcount == 0) { + if (s->id) + g_source_remove (s->id); + if (s->channel) { + /* Don't shut down the channel since systemd will soon close + * the file descriptor itself, which would cause -EBADF. + */ + g_io_channel_unref (s->channel); + } + g_free (s); + } + return NULL; +} + +int +sd_event_source_set_description(sd_event_source *s, const char *description) +{ + if (!s) + return -EINVAL; + + g_source_set_name_by_id (s->id, description); + return 0; +} + +static gboolean +io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *source) +{ + int r, revents = 0; + + if (condition & G_IO_IN) + revents |= EPOLLIN; + if (condition & G_IO_OUT) + revents |= EPOLLOUT; + if (condition & G_IO_PRI) + revents |= EPOLLPRI; + if (condition & G_IO_ERR) + revents |= EPOLLERR; + if (condition & G_IO_HUP) + revents |= EPOLLHUP; + + r = source->io_cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data); + if (r < 0) { + source->id = 0; + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; +} + +int +sd_event_add_io (sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata) +{ + struct sd_event_source *source; + GIOChannel *channel; + GIOCondition condition = 0; + + channel = g_io_channel_unix_new (fd); + if (!channel) + return -EINVAL; + + source = g_new0 (struct sd_event_source, 1); + source->refcount = 1; + source->io_cb = callback; + source->user_data = userdata; + source->channel = channel; + + if (events & EPOLLIN) + condition |= G_IO_IN; + if (events & EPOLLOUT) + condition |= G_IO_OUT; + if (events & EPOLLPRI) + condition |= G_IO_PRI; + if (events & EPOLLERR) + condition |= G_IO_ERR; + if (events & EPOLLHUP) + condition |= G_IO_HUP; + + g_io_channel_set_encoding (source->channel, NULL, NULL); + g_io_channel_set_buffered (source->channel, FALSE); + source->id = g_io_add_watch (source->channel, condition, (GIOFunc) io_ready, source); + + *s = source; + return 0; +} + +static gboolean +time_ready (struct sd_event_source *source) +{ + int r; + + r = source->time_cb (source, source->usec, source->user_data); + if (r < 0) { + source->id = 0; + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; +} + +int +sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata) +{ + struct sd_event_source *source; + uint64_t n = now (clock); + + source = g_new0 (struct sd_event_source, 1); + source->refcount = 1; + source->time_cb = callback; + source->user_data = userdata; + source->usec = usec; + + if (usec > 1000) + usec = n < usec - 1000 ? usec - n : 1000; + source->id = g_timeout_add (usec / 1000, (GSourceFunc) time_ready, source); + + *s = source; + return 0; +} + +/* sd_event is basically a GMainContext; but since we only + * ever use the default context, nothing to do here. + */ + +int +sd_event_default (sd_event **e) +{ + *e = GUINT_TO_POINTER (1); + return 0; +} + +sd_event* +sd_event_ref (sd_event *e) +{ + return e; +} + +sd_event* +sd_event_unref (sd_event *e) +{ + return NULL; +} + +int +sd_event_now (sd_event *e, clockid_t clock, uint64_t *usec) +{ + *usec = now (clock); + return 0; +} + +int asynchronous_close(int fd) { + safe_close(fd); + return -1; +} + diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h new file mode 100644 index 00000000..ce1716b1 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h @@ -0,0 +1,109 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef NM_SD_ADAPT_H +#define NM_SD_ADAPT_H + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_AUXV_H +#include +#endif +#include +#include + +#include "nm-logging.h" + +static inline guint32 +_slog_level_to_nm (int slevel) +{ + switch (slevel) { + case LOG_DEBUG: return LOGL_DEBUG; + case LOG_WARNING: return LOGL_WARN; + case LOG_ERR: return LOGL_ERR; + case LOG_INFO: + case LOG_NOTICE: + default: return LOGL_INFO; + } +} + +#define log_meta(level, file, line, func, format, ...) \ +G_STMT_START { \ + guint32 _l = _slog_level_to_nm ((level)); \ + if (nm_logging_enabled (_l, LOGD_DHCP)) { \ + const char *_location = strrchr (file "", '/'); \ + \ + _nm_log (_location ? _location + 1 : file, line, func, _l, LOGD_DHCP, format, ## __VA_ARGS__); \ + } \ +} G_STMT_END + +#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__) +#define log_error(...) log_full(LOG_ERR, __VA_ARGS__) +#define log_full(level, ...) log_meta((level), __FILE__, __LINE__, __func__, __VA_ARGS__); + +#define log_dhcp_client(client, fmt, ...) \ + log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) + +#define log_assert_failed(e, file, line, func) \ +G_STMT_START { \ + nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assertion failed: " # e); \ + g_assert (FALSE); \ +} G_STMT_END + +#define log_assert_failed_unreachable(t, file, line, func) \ +G_STMT_START { \ + nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assert unreachable: " # t); \ + g_assert_not_reached (); \ +} G_STMT_END + +#define log_assert_failed_return(e, file, line, func) \ + nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assert return: " # e); \ + +#define log_oom nm_log_err(LOGD_CORE, "%s:%s/%s: OOM", __FILE__, __LINE__, __func__) + +/* Can't include both net/if.h and linux/if.h; so have to define this here */ +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +#ifndef MAX_HANDLE_SZ +#define MAX_HANDLE_SZ 128 +#endif + +#define noreturn G_GNUC_NORETURN + +#include "sd-id128.h" +#include "sparse-endian.h" +#include "async.h" +#include "util.h" + +static inline pid_t gettid(void) { + return (pid_t) syscall(SYS_gettid); +} + +#endif /* NM_SD_ADAPT_H */ + diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h new file mode 100644 index 00000000..28c0e634 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h @@ -0,0 +1,76 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + 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 . +***/ + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include + +#include "socket-util.h" + +#include "sd-dhcp-client.h" +#include "dhcp-protocol.h" + +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, + uint32_t xid, const uint8_t *mac_addr, + size_t mac_addr_len, uint16_t arp_type); +int dhcp_network_bind_udp_socket(be32_t address, uint16_t port); +int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, + const void *packet, size_t len); +int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, + const void *packet, size_t len); + +int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload, + uint8_t code, size_t optlen, const void *optval); + +typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len, + const uint8_t *option, void *user_data); + +int dhcp_option_parse(DHCPMessage *message, size_t len, + dhcp_option_cb_t cb, void *user_data); + +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, + uint8_t type, uint16_t arp_type, size_t optlen, + size_t *optoffset); + +uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len); + +void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr, + uint16_t source, be32_t destination_addr, + uint16_t destination, uint16_t len); + +int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum); + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref); +#define _cleanup_dhcp_client_unref_ _cleanup_(sd_dhcp_client_unrefp) + +/* If we are invoking callbacks of a dhcp-client, ensure unreffing the + * client from the callback doesn't destroy the object we are working + * on */ +#define DHCP_CLIENT_DONT_DESTROY(client) \ + _cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) + +#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h new file mode 100644 index 00000000..9e184ac4 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h @@ -0,0 +1,87 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + 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 . +***/ + +#include +#include + +#include "refcnt.h" +#include "util.h" + +#include "dhcp-protocol.h" + +#include "sd-dhcp-client.h" + +struct sd_dhcp_route { + struct in_addr dst_addr; + struct in_addr gw_addr; + unsigned char dst_prefixlen; +}; + +struct sd_dhcp_lease { + RefCount n_ref; + + int32_t time_offset; + uint32_t t1; + uint32_t t2; + uint32_t lifetime; + uint32_t mtu_aging_timeout; + be32_t address; + be32_t server_address; + be32_t subnet_mask; + be32_t router; + be32_t next_server; + be32_t broadcast; + struct in_addr *dns; + size_t dns_size; + struct in_addr *ntp; + size_t ntp_size; + struct in_addr *policy_filter; + size_t policy_filter_size; + struct sd_dhcp_route *static_route; + size_t static_route_size; + size_t static_route_allocated; + uint16_t boot_file_size; + uint16_t mdr; + uint16_t mtu; + uint8_t ttl; + bool ip_forward; + bool ip_forward_non_local; + char *domainname; + char *hostname; + char *root_path; + uint8_t *client_id; + size_t client_id_len; +}; + +int dhcp_lease_new(sd_dhcp_lease **ret); +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, + void *user_data); + +int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease); + +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, + size_t client_id_len); + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref); +#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp) diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c new file mode 100644 index 00000000..971b3aa1 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c @@ -0,0 +1,241 @@ +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "socket-util.h" + +#include "dhcp-internal.h" + +static int _bind_raw_socket(int ifindex, union sockaddr_union *link, + uint32_t xid, const uint8_t *mac_addr, + size_t mac_addr_len, + const uint8_t *bcast_addr, + const struct ether_addr *eth_mac, + uint16_t arp_type, uint8_t dhcp_hlen) { + struct sock_filter filter[] = { + BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */ + BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.protocol)), /* A <- IP protocol */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol == UDP ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags */ + BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x20), /* A <- A & 0x20 (More Fragments bit) */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags + Fragment offset */ + BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x1fff), /* A <- A & 0x1fff (Fragment offset) */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)), /* A <- DHCP op */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), /* op == BOOTREPLY ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)), /* A <- DHCP header type */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0), /* header type == arp_type ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- mac address length */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), /* address length == dhcp_hlen ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))), /* A <- 4 bytes of client's MAC */ + BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */ + BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */ + BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */ + BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)), /* A <- DHCP magic cookie */ + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0), /* cookie == DHCP magic cookie ? */ + BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */ + BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */ + }; + struct sock_fprog fprog = { + .len = ELEMENTSOF(filter), + .filter = filter + }; + _cleanup_close_ int s = -1; + int r, on = 1; + + assert(ifindex > 0); + assert(link); + + s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + if (s < 0) + return -errno; + + r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on)); + if (r < 0) + return -errno; + + r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)); + if (r < 0) + return -errno; + + link->ll.sll_family = AF_PACKET; + link->ll.sll_protocol = htons(ETH_P_IP); + link->ll.sll_ifindex = ifindex; + link->ll.sll_hatype = htons(arp_type); + link->ll.sll_halen = mac_addr_len; + memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len); + + r = bind(s, &link->sa, sizeof(link->ll)); + if (r < 0) + return -errno; + + r = s; + s = -1; + + return r; +} + +int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, + uint32_t xid, const uint8_t *mac_addr, + size_t mac_addr_len, uint16_t arp_type) { + static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + /* Default broadcast address for IPoIB */ + static const uint8_t ib_bcast[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0x12, 0x40, 0x1b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff + }; + struct ether_addr eth_mac = { { 0, 0, 0, 0, 0, 0 } }; + const uint8_t *bcast_addr = NULL; + uint8_t dhcp_hlen = 0; + + assert_return(mac_addr_len > 0, -EINVAL); + + if (arp_type == ARPHRD_ETHER) { + assert_return(mac_addr_len == ETH_ALEN, -EINVAL); + memcpy(ð_mac, mac_addr, ETH_ALEN); + bcast_addr = eth_bcast; + dhcp_hlen = ETH_ALEN; + } else if (arp_type == ARPHRD_INFINIBAND) { + assert_return(mac_addr_len == INFINIBAND_ALEN, -EINVAL); + bcast_addr = ib_bcast; + } else + return -EINVAL; + + return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len, + bcast_addr, ð_mac, arp_type, dhcp_hlen); +} + +int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) { + union sockaddr_union src = { + .in.sin_family = AF_INET, + .in.sin_port = htobe16(port), + .in.sin_addr.s_addr = address, + }; + _cleanup_close_ int s = -1; + int r, on = 1, tos = IPTOS_CLASS_CS6; + + s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + if (s < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)); + if (r < 0) + return -errno; + + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (r < 0) + return -errno; + + if (address == INADDR_ANY) { + r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); + if (r < 0) + return -errno; + + r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + if (r < 0) + return -errno; + } else { + r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)); + if (r < 0) + return -errno; + } + + r = bind(s, &src.sa, sizeof(src.in)); + if (r < 0) + return -errno; + + r = s; + s = -1; + + return r; +} + +int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, + const void *packet, size_t len) { + int r; + + assert(link); + assert(packet); + assert(len); + + r = sendto(s, packet, len, 0, &link->sa, sizeof(link->ll)); + if (r < 0) + return -errno; + + return 0; +} + +int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, + const void *packet, size_t len) { + union sockaddr_union dest = { + .in.sin_family = AF_INET, + .in.sin_port = htobe16(port), + .in.sin_addr.s_addr = address, + }; + int r; + + assert(s >= 0); + assert(packet); + assert(len); + + r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)); + if (r < 0) + return -errno; + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c new file mode 100644 index 00000000..9759e575 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c @@ -0,0 +1,257 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include + +#include "dhcp-internal.h" + +static int option_append(uint8_t options[], size_t size, size_t *offset, + uint8_t code, size_t optlen, const void *optval) { + assert(options); + assert(offset); + + if (code != DHCP_OPTION_END) + /* always make sure there is space for an END option */ + size --; + + switch (code) { + + case DHCP_OPTION_PAD: + case DHCP_OPTION_END: + if (size < *offset + 1) + return -ENOBUFS; + + options[*offset] = code; + *offset += 1; + break; + + default: + if (size < *offset + optlen + 2) + return -ENOBUFS; + + options[*offset] = code; + options[*offset + 1] = optlen; + + if (optlen) { + assert(optval); + + memcpy(&options[*offset + 2], optval, optlen); + } + + *offset += optlen + 2; + + break; + } + + return 0; +} + +int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, + uint8_t overload, + uint8_t code, size_t optlen, const void *optval) { + size_t file_offset = 0, sname_offset =0; + bool file, sname; + int r; + + assert(message); + assert(offset); + + file = overload & DHCP_OVERLOAD_FILE; + sname = overload & DHCP_OVERLOAD_SNAME; + + if (*offset < size) { + /* still space in the options array */ + r = option_append(message->options, size, offset, code, optlen, optval); + if (r >= 0) + return 0; + else if (r == -ENOBUFS && (file || sname)) { + /* did not fit, but we have more buffers to try + close the options array and move the offset to its end */ + r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL); + if (r < 0) + return r; + + *offset = size; + } else + return r; + } + + if (overload & DHCP_OVERLOAD_FILE) { + file_offset = *offset - size; + + if (file_offset < sizeof(message->file)) { + /* still space in the 'file' array */ + r = option_append(message->file, sizeof(message->file), &file_offset, code, optlen, optval); + if (r >= 0) { + *offset = size + file_offset; + return 0; + } else if (r == -ENOBUFS && sname) { + /* did not fit, but we have more buffers to try + close the file array and move the offset to its end */ + r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL); + if (r < 0) + return r; + + *offset = size + sizeof(message->file); + } else + return r; + } + } + + if (overload & DHCP_OVERLOAD_SNAME) { + sname_offset = *offset - size - (file ? sizeof(message->file) : 0); + + if (sname_offset < sizeof(message->sname)) { + /* still space in the 'sname' array */ + r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval); + if (r >= 0) { + *offset = size + (file ? sizeof(message->file) : 0) + sname_offset; + return 0; + } else { + /* no space, or other error, give up */ + return r; + } + } + } + + return -ENOBUFS; +} + +static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload, + uint8_t *message_type, dhcp_option_cb_t cb, + void *user_data) { + uint8_t code, len; + size_t offset = 0; + + while (offset < buflen) { + switch (options[offset]) { + case DHCP_OPTION_PAD: + offset++; + + break; + + case DHCP_OPTION_END: + return 0; + + case DHCP_OPTION_MESSAGE_TYPE: + if (buflen < offset + 3) + return -ENOBUFS; + + len = options[++offset]; + if (len != 1) + return -EINVAL; + + if (message_type) + *message_type = options[++offset]; + else + offset++; + + offset++; + + break; + + case DHCP_OPTION_OVERLOAD: + if (buflen < offset + 3) + return -ENOBUFS; + + len = options[++offset]; + if (len != 1) + return -EINVAL; + + if (overload) + *overload = options[++offset]; + else + offset++; + + offset++; + + break; + + default: + if (buflen < offset + 3) + return -ENOBUFS; + + code = options[offset]; + len = options[++offset]; + + if (buflen < ++offset + len) + return -EINVAL; + + if (cb) + cb(code, len, &options[offset], user_data); + + offset += len; + + break; + } + } + + if (offset < buflen) + return -EINVAL; + + return 0; +} + +int dhcp_option_parse(DHCPMessage *message, size_t len, + dhcp_option_cb_t cb, void *user_data) { + uint8_t overload = 0; + uint8_t message_type = 0; + int r; + + if (!message) + return -EINVAL; + + if (len < sizeof(DHCPMessage)) + return -EINVAL; + + len -= sizeof(DHCPMessage); + + r = parse_options(message->options, len, &overload, &message_type, + cb, user_data); + if (r < 0) + return r; + + if (overload & DHCP_OVERLOAD_FILE) { + r = parse_options(message->file, sizeof(message->file), + NULL, &message_type, cb, user_data); + if (r < 0) + return r; + } + + if (overload & DHCP_OVERLOAD_SNAME) { + r = parse_options(message->sname, sizeof(message->sname), + NULL, &message_type, cb, user_data); + if (r < 0) + return r; + } + + if (message_type) + return message_type; + + return -ENOMSG; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c new file mode 100644 index 00000000..5bb065ba --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c @@ -0,0 +1,204 @@ +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "list.h" + +#include "dhcp-protocol.h" +#include "dhcp-lease-internal.h" +#include "dhcp-internal.h" +#include "sd-dhcp-lease.h" +#include "sd-dhcp-client.h" + +#define DHCP_CLIENT_MIN_OPTIONS_SIZE 312 + +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, + uint8_t type, uint16_t arp_type, size_t optlen, + size_t *optoffset) { + size_t offset = 0; + int r; + + assert(op == BOOTREQUEST || op == BOOTREPLY); + assert(arp_type == ARPHRD_ETHER || arp_type == ARPHRD_INFINIBAND); + + message->op = op; + message->htype = arp_type; + message->hlen = (arp_type == ARPHRD_ETHER) ? ETHER_ADDR_LEN : 0; + message->xid = htobe32(xid); + message->magic = htobe32(DHCP_MAGIC_COOKIE); + + r = dhcp_option_append(message, optlen, &offset, 0, + DHCP_OPTION_MESSAGE_TYPE, 1, &type); + if (r < 0) + return r; + + *optoffset = offset; + + return 0; +} + +uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len) { + uint64_t *buf_64 = (uint64_t*)buf; + uint64_t *end_64 = buf_64 + (len / sizeof(uint64_t)); + uint64_t sum = 0; + + /* See RFC1071 */ + + while (buf_64 < end_64) { + sum += *buf_64; + if (sum < *buf_64) + /* wrap around in one's complement */ + sum++; + + buf_64 ++; + } + + if (len % sizeof(uint64_t)) { + /* If the buffer is not aligned to 64-bit, we need + to zero-pad the last few bytes and add them in */ + uint64_t buf_tail = 0; + + memcpy(&buf_tail, buf_64, len % sizeof(uint64_t)); + + sum += buf_tail; + if (sum < buf_tail) + /* wrap around */ + sum++; + } + + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + + return ~sum; +} + +void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr, + uint16_t source_port, be32_t destination_addr, + uint16_t destination_port, uint16_t len) { + packet->ip.version = IPVERSION; + packet->ip.ihl = DHCP_IP_SIZE / 4; + packet->ip.tot_len = htobe16(len); + + packet->ip.tos = IPTOS_CLASS_CS6; + + packet->ip.protocol = IPPROTO_UDP; + packet->ip.saddr = source_addr; + packet->ip.daddr = destination_addr; + + packet->udp.source = htobe16(source_port); + packet->udp.dest = htobe16(destination_port); + + packet->udp.len = htobe16(len - DHCP_IP_SIZE); + + packet->ip.check = packet->udp.len; + packet->udp.check = dhcp_packet_checksum((uint8_t*)&packet->ip.ttl, len - 8); + + packet->ip.ttl = IPDEFTTL; + packet->ip.check = 0; + packet->ip.check = dhcp_packet_checksum((uint8_t*)&packet->ip, DHCP_IP_SIZE); +} + +int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) { + size_t hdrlen; + + assert(packet); + + /* IP */ + + if (packet->ip.version != IPVERSION) { + log_debug("ignoring packet: not IPv4"); + return -EINVAL; + } + + if (packet->ip.ihl < 5) { + log_debug("ignoring packet: IPv4 IHL (%u words) invalid", + packet->ip.ihl); + return -EINVAL; + } + + hdrlen = packet->ip.ihl * 4; + if (hdrlen < 20) { + log_debug("ignoring packet: IPv4 IHL (%zu bytes) " + "smaller than minimum (20 bytes)", hdrlen); + return -EINVAL; + } + + if (len < hdrlen) { + log_debug("ignoring packet: packet (%zu bytes) " + "smaller than expected (%zu) by IP header", len, + hdrlen); + return -EINVAL; + } + + /* UDP */ + + if (packet->ip.protocol != IPPROTO_UDP) { + log_debug("ignoring packet: not UDP"); + return -EINVAL; + } + + if (len < hdrlen + be16toh(packet->udp.len)) { + log_debug("ignoring packet: packet (%zu bytes) " + "smaller than expected (%zu) by UDP header", len, + hdrlen + be16toh(packet->udp.len)); + return -EINVAL; + } + + if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) { + log_debug("ignoring packet: to port %u, which " + "is not the DHCP client port (%u)", + be16toh(packet->udp.dest), DHCP_PORT_CLIENT); + return -EINVAL; + } + + /* checksums - computing these is relatively expensive, so only do it + if all the other checks have passed + */ + + if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen)) { + log_debug("ignoring packet: invalid IP checksum"); + return -EINVAL; + } + + if (checksum && packet->udp.check) { + packet->ip.check = packet->udp.len; + packet->ip.ttl = 0; + + if (dhcp_packet_checksum((uint8_t*)&packet->ip.ttl, + be16toh(packet->udp.len) + 12)) { + log_debug("ignoring packet: invalid UDP checksum"); + return -EINVAL; + } + } + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h new file mode 100644 index 00000000..abca9422 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h @@ -0,0 +1,141 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include +#include +#include + +#include "macro.h" +#include "sparse-endian.h" + +struct DHCPMessage { + uint8_t op; + uint8_t htype; + uint8_t hlen; + uint8_t hops; + be32_t xid; + be16_t secs; + be16_t flags; + be32_t ciaddr; + be32_t yiaddr; + be32_t siaddr; + be32_t giaddr; + uint8_t chaddr[16]; + uint8_t sname[64]; + uint8_t file[128]; + be32_t magic; + uint8_t options[0]; +} _packed_; + +typedef struct DHCPMessage DHCPMessage; + +struct DHCPPacket { + struct iphdr ip; + struct udphdr udp; + DHCPMessage dhcp; +} _packed_; + +typedef struct DHCPPacket DHCPPacket; + +#define DHCP_IP_SIZE (int32_t)(sizeof(struct iphdr)) +#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_MAGIC_COOKIE (uint32_t)(0x63825363) + +enum { + DHCP_PORT_SERVER = 67, + DHCP_PORT_CLIENT = 68, +}; + +enum DHCPState { + DHCP_STATE_INIT = 0, + DHCP_STATE_SELECTING = 1, + DHCP_STATE_INIT_REBOOT = 2, + DHCP_STATE_REBOOTING = 3, + DHCP_STATE_REQUESTING = 4, + DHCP_STATE_BOUND = 5, + DHCP_STATE_RENEWING = 6, + DHCP_STATE_REBINDING = 7, + DHCP_STATE_STOPPED = 8, +}; + +typedef enum DHCPState DHCPState; + +enum { + BOOTREQUEST = 1, + BOOTREPLY = 2, +}; + +enum { + DHCP_DISCOVER = 1, + DHCP_OFFER = 2, + DHCP_REQUEST = 3, + DHCP_DECLINE = 4, + DHCP_ACK = 5, + DHCP_NAK = 6, + DHCP_RELEASE = 7, + DHCP_INFORM = 8, + DHCP_FORCERENEW = 9, +}; + +enum { + DHCP_OVERLOAD_FILE = 1, + DHCP_OVERLOAD_SNAME = 2, +}; + +enum { + DHCP_OPTION_PAD = 0, + DHCP_OPTION_SUBNET_MASK = 1, + DHCP_OPTION_TIME_OFFSET = 2, + DHCP_OPTION_ROUTER = 3, + DHCP_OPTION_DOMAIN_NAME_SERVER = 6, + DHCP_OPTION_HOST_NAME = 12, + DHCP_OPTION_BOOT_FILE_SIZE = 13, + DHCP_OPTION_DOMAIN_NAME = 15, + DHCP_OPTION_ROOT_PATH = 17, + DHCP_OPTION_ENABLE_IP_FORWARDING = 19, + DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20, + DHCP_OPTION_POLICY_FILTER = 21, + DHCP_OPTION_INTERFACE_MDR = 22, + DHCP_OPTION_INTERFACE_TTL = 23, + DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24, + DHCP_OPTION_INTERFACE_MTU = 26, + DHCP_OPTION_BROADCAST = 28, + DHCP_OPTION_STATIC_ROUTE = 33, + DHCP_OPTION_NTP_SERVER = 42, + DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, + DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, + DHCP_OPTION_OVERLOAD = 52, + DHCP_OPTION_MESSAGE_TYPE = 53, + DHCP_OPTION_SERVER_IDENTIFIER = 54, + DHCP_OPTION_PARAMETER_REQUEST_LIST = 55, + DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57, + DHCP_OPTION_RENEWAL_T1_TIME = 58, + DHCP_OPTION_REBINDING_T2_TIME = 59, + DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, + DHCP_OPTION_CLIENT_IDENTIFIER = 61, + DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, + DHCP_OPTION_END = 255, +}; diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h new file mode 100644 index 00000000..e29e2f0e --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h @@ -0,0 +1,81 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "nm-sd-adapt.h" + +#include +#include + +#include "sparse-endian.h" +#include "sd-event.h" +#include "list.h" +#include "macro.h" + +typedef struct DHCP6Address DHCP6Address; + +struct DHCP6Address { + LIST_FIELDS(DHCP6Address, addresses); + + struct { + struct in6_addr address; + be32_t lifetime_preferred; + be32_t lifetime_valid; + } iaaddr _packed_; +}; + +struct DHCP6IA { + uint16_t type; + struct { + be32_t id; + be32_t lifetime_t1; + be32_t lifetime_t2; + } _packed_; + sd_event_source *timeout_t1; + sd_event_source *timeout_t2; + + LIST_HEAD(DHCP6Address, addresses); +}; + +typedef struct DHCP6IA DHCP6IA; + +#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) + +int dhcp_network_icmp6_bind_router_solicitation(int index); +int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); + +int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, + size_t optlen, const void *optval); +int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia); +int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, + size_t *optlen, uint8_t **optvalue); +int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, + DHCP6IA *ia); + +int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address); +int dhcp6_network_send_udp_socket(int s, struct in6_addr *address, + const void *packet, size_t len); + +const char *dhcp6_message_type_to_string(int s) _const_; +int dhcp6_message_type_from_string(const char *s) _pure_; +const char *dhcp6_message_status_to_string(int s) _const_; +int dhcp6_message_status_from_string(const char *s) _pure_; diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h new file mode 100644 index 00000000..9f7826c4 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h @@ -0,0 +1,64 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "nm-sd-adapt.h" + +#include + +#include "refcnt.h" + +#include "sd-dhcp6-lease.h" +#include "dhcp6-internal.h" + +struct sd_dhcp6_lease { + RefCount n_ref; + + uint8_t *serverid; + size_t serverid_len; + uint8_t preference; + bool rapid_commit; + + DHCP6IA ia; + + DHCP6Address *addr_iter; +}; + +int dhcp6_lease_clear_timers(DHCP6IA *ia); +int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire); +DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia); + +int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, + size_t len); +int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len); +int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference); +int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference); +int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease); +int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit); + +int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid); + +int dhcp6_lease_new(sd_dhcp6_lease **ret); + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref); +#define _cleanup_dhcp6_lease_free_ _cleanup_(sd_dhcp6_lease_unrefp) diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c new file mode 100644 index 00000000..fbb20ef9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c @@ -0,0 +1,198 @@ +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "socket-util.h" + +#include "dhcp6-internal.h" +#include "dhcp6-protocol.h" + +#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } } + +#define IN6ADDR_ALL_NODES_MULTICAST_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } } + +int dhcp_network_icmp6_bind_router_solicitation(int index) +{ + struct icmp6_filter filter = { }; + struct ipv6_mreq mreq = { + .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT, + .ipv6mr_interface = index, + }; + _cleanup_close_ int s = -1; + int r, zero = 0, hops = 255; + + s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, + IPPROTO_ICMPV6); + if (s < 0) + return -errno; + + ICMP6_FILTER_SETBLOCKALL(&filter); + ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); + r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, + sizeof(filter)); + if (r < 0) + return -errno; + + /* RFC 3315, section 6.7, bullet point 2 may indicate that an + IPV6_PKTINFO socket option also applies for ICMPv6 multicast. + Empirical experiments indicates otherwise and therefore an + IPV6_MULTICAST_IF socket option is used here instead */ + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index, + sizeof(index)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero, + sizeof(zero)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, + sizeof(hops)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)); + if (r < 0) + return -errno; + + r = s; + s = -1; + return r; +} + +int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) +{ + struct sockaddr_in6 dst = { + .sin6_family = AF_INET6, + .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT, + }; + struct { + struct nd_router_solicit rs; + struct nd_opt_hdr rs_opt; + struct ether_addr rs_opt_mac; + } _packed_ rs = { + .rs.nd_rs_type = ND_ROUTER_SOLICIT, + }; + struct iovec iov[1] = { + { &rs, }, + }; + struct msghdr msg = { + .msg_name = &dst, + .msg_namelen = sizeof(dst), + .msg_iov = iov, + .msg_iovlen = 1, + }; + int r; + + if (ether_addr) { + memcpy(&rs.rs_opt_mac, ether_addr, ETH_ALEN); + rs.rs_opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR; + rs.rs_opt.nd_opt_len = 1; + iov[0].iov_len = sizeof(rs); + } else + iov[0].iov_len = sizeof(rs.rs); + + r = sendmsg(s, &msg, 0); + if (r < 0) + return -errno; + + return 0; +} + +int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) { + struct in6_pktinfo pktinfo = { + .ipi6_ifindex = index, + }; + union sockaddr_union src = { + .in6.sin6_family = AF_INET6, + .in6.sin6_port = htobe16(DHCP6_PORT_CLIENT), + .in6.sin6_addr = IN6ADDR_ANY_INIT, + }; + _cleanup_close_ int s = -1; + int r, off = 0, on = 1; + + if (local_address) + memcpy(&src.in6.sin6_addr, local_address, + sizeof(src.in6.sin6_addr)); + + s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, + IPPROTO_UDP); + if (s < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &pktinfo, + sizeof(pktinfo)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); + if (r < 0) + return -errno; + + r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off)); + if (r < 0) + return -errno; + + r = bind(s, &src.sa, sizeof(src.in6)); + if (r < 0) + return -errno; + + r = s; + s = -1; + return r; +} + +int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, + const void *packet, size_t len) { + union sockaddr_union dest = { + .in6.sin6_family = AF_INET6, + .in6.sin6_port = htobe16(DHCP6_PORT_SERVER), + }; + int r; + + assert(server_address); + + memcpy(&dest.in6.sin6_addr, server_address, sizeof(dest.in6.sin6_addr)); + + r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in6)); + if (r < 0) + return -errno; + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c new file mode 100644 index 00000000..3d6e2462 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c @@ -0,0 +1,323 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include + +#include "sparse-endian.h" +#include "unaligned.h" +#include "util.h" + +#include "dhcp6-internal.h" +#include "dhcp6-protocol.h" + +#define DHCP6_OPTION_IA_NA_LEN 12 +#define DHCP6_OPTION_IA_TA_LEN 4 + +typedef struct DHCP6Option { + be16_t code; + be16_t len; + uint8_t data[]; +} _packed_ DHCP6Option; + +static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, + size_t optlen) { + DHCP6Option *option = (DHCP6Option*) *buf; + + assert_return(buf, -EINVAL); + assert_return(*buf, -EINVAL); + assert_return(buflen, -EINVAL); + + if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option)) + return -ENOBUFS; + + option->code = htobe16(optcode); + option->len = htobe16(optlen); + + *buf += sizeof(DHCP6Option); + *buflen -= sizeof(DHCP6Option); + + return 0; +} + +int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, + size_t optlen, const void *optval) { + int r; + + assert_return(optval || optlen == 0, -EINVAL); + + r = option_append_hdr(buf, buflen, code, optlen); + if (r < 0) + return r; + + if (optval) + memcpy(*buf, optval, optlen); + + *buf += optlen; + *buflen -= optlen; + + return 0; +} + +int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { + uint16_t len; + uint8_t *ia_hdr; + size_t ia_buflen, ia_addrlen = 0; + DHCP6Address *addr; + int r; + + assert_return(buf && *buf && buflen && ia, -EINVAL); + + switch (ia->type) { + case DHCP6_OPTION_IA_NA: + len = DHCP6_OPTION_IA_NA_LEN; + break; + + case DHCP6_OPTION_IA_TA: + len = DHCP6_OPTION_IA_TA_LEN; + break; + + default: + return -EINVAL; + } + + if (*buflen < len) + return -ENOBUFS; + + ia_hdr = *buf; + ia_buflen = *buflen; + + *buf += sizeof(DHCP6Option); + *buflen -= sizeof(DHCP6Option); + + memcpy(*buf, &ia->id, len); + + *buf += len; + *buflen -= len; + + LIST_FOREACH(addresses, addr, ia->addresses) { + r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR, + sizeof(addr->iaaddr)); + if (r < 0) + return r; + + memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr)); + + *buf += sizeof(addr->iaaddr); + *buflen -= sizeof(addr->iaaddr); + + ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr); + } + + r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen); + if (r < 0) + return r; + + return 0; +} + + +static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) { + DHCP6Option *option = (DHCP6Option*) *buf; + uint16_t len; + + assert_return(buf, -EINVAL); + assert_return(optcode, -EINVAL); + assert_return(optlen, -EINVAL); + + if (*buflen < sizeof(DHCP6Option)) + return -ENOMSG; + + len = be16toh(option->len); + + if (len > *buflen) + return -ENOMSG; + + *optcode = be16toh(option->code); + *optlen = len; + + *buf += 4; + *buflen -= 4; + + return 0; +} + +int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, + size_t *optlen, uint8_t **optvalue) { + int r; + + assert_return(buf && buflen && optcode && optlen && optvalue, -EINVAL); + + r = option_parse_hdr(buf, buflen, optcode, optlen); + if (r < 0) + return r; + + if (*optlen > *buflen) + return -ENOBUFS; + + *optvalue = *buf; + *buflen -= *optlen; + *buf += *optlen; + + return 0; +} + +int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, + DHCP6IA *ia) { + int r; + uint16_t opt, status; + size_t optlen; + size_t iaaddr_offset; + DHCP6Address *addr; + uint32_t lt_t1, lt_t2, lt_valid, lt_pref, lt_min = ~0; + + assert_return(ia, -EINVAL); + assert_return(!ia->addresses, -EINVAL); + + switch (iatype) { + case DHCP6_OPTION_IA_NA: + + if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) + + sizeof(addr->iaaddr)) { + r = -ENOBUFS; + goto error; + } + + iaaddr_offset = DHCP6_OPTION_IA_NA_LEN; + memcpy(&ia->id, *buf, iaaddr_offset); + + lt_t1 = be32toh(ia->lifetime_t1); + lt_t2 = be32toh(ia->lifetime_t2); + + if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { + log_dhcp6_client(client, "IA T1 %ds > T2 %ds", + lt_t1, lt_t2); + r = -EINVAL; + goto error; + } + + break; + + case DHCP6_OPTION_IA_TA: + if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) + + sizeof(addr->iaaddr)) { + r = -ENOBUFS; + goto error; + } + + iaaddr_offset = DHCP6_OPTION_IA_TA_LEN; + memcpy(&ia->id, *buf, iaaddr_offset); + + ia->lifetime_t1 = 0; + ia->lifetime_t2 = 0; + + break; + + default: + r = -ENOMSG; + goto error; + } + + ia->type = iatype; + + *buflen -= iaaddr_offset; + *buf += iaaddr_offset; + + while ((r = option_parse_hdr(buf, buflen, &opt, &optlen)) >= 0) { + + switch (opt) { + case DHCP6_OPTION_IAADDR: + + addr = new0(DHCP6Address, 1); + if (!addr) { + r = -ENOMEM; + goto error; + } + + LIST_INIT(addresses, addr); + + memcpy(&addr->iaaddr, *buf, sizeof(addr->iaaddr)); + + lt_valid = be32toh(addr->iaaddr.lifetime_valid); + lt_pref = be32toh(addr->iaaddr.lifetime_valid); + + if (!lt_valid || lt_pref > lt_valid) { + log_dhcp6_client(client, "IA preferred %ds > valid %ds", + lt_pref, lt_valid); + free(addr); + } else { + LIST_PREPEND(addresses, ia->addresses, addr); + if (lt_valid < lt_min) + lt_min = lt_valid; + } + + break; + + case DHCP6_OPTION_STATUS_CODE: + if (optlen < sizeof(status)) + break; + + status = (*buf)[0] << 8 | (*buf)[1]; + if (status) { + log_dhcp6_client(client, "IA status %d", + status); + r = -EINVAL; + goto error; + } + + break; + + default: + log_dhcp6_client(client, "Unknown IA option %d", opt); + break; + } + + *buflen -= optlen; + *buf += optlen; + } + + if (r == -ENOMSG) + r = 0; + + if (!ia->lifetime_t1 && !ia->lifetime_t2) { + lt_t1 = lt_min / 2; + lt_t2 = lt_min / 10 * 8; + ia->lifetime_t1 = htobe32(lt_t1); + ia->lifetime_t2 = htobe32(lt_t2); + + log_dhcp6_client(client, "Computed IA T1 %ds and T2 %ds as both were zero", + lt_t1, lt_t2); + } + + if (*buflen) + r = -ENOMSG; + +error: + *buf += *buflen; + *buflen = 0; + + return r; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h new file mode 100644 index 00000000..eaa67171 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h @@ -0,0 +1,141 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include +#include + +#include "macro.h" +#include "sparse-endian.h" + +struct DHCP6Message { + union { + struct { + uint8_t type; + uint8_t _pad[3]; + } _packed_; + be32_t transaction_id; + }; +} _packed_; + +typedef struct DHCP6Message DHCP6Message; + +#define DHCP6_MIN_OPTIONS_SIZE \ + 1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) + +#define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } } + +enum { + DHCP6_PORT_SERVER = 547, + DHCP6_PORT_CLIENT = 546, +}; + +#define DHCP6_SOL_MAX_DELAY 1 * USEC_PER_SEC +#define DHCP6_SOL_TIMEOUT 1 * USEC_PER_SEC +#define DHCP6_SOL_MAX_RT 120 * USEC_PER_SEC +#define DHCP6_REQ_TIMEOUT 1 * USEC_PER_SEC +#define DHCP6_REQ_MAX_RT 120 * USEC_PER_SEC +#define DHCP6_REQ_MAX_RC 10 +#define DHCP6_REN_TIMEOUT 10 * USEC_PER_SEC +#define DHCP6_REN_MAX_RT 600 * USEC_PER_SEC +#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC +#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC + +enum { + DHCP6_DUID_LLT = 1, + DHCP6_DUID_EN = 2, + DHCP6_DUID_LL = 3, + DHCP6_DUID_UUID = 4, +}; + +enum DHCP6State { + DHCP6_STATE_STOPPED = 0, + DHCP6_STATE_SOLICITATION = 2, + DHCP6_STATE_REQUEST = 3, + DHCP6_STATE_BOUND = 4, + DHCP6_STATE_RENEW = 5, + DHCP6_STATE_REBIND = 6, +}; + +enum { + DHCP6_SOLICIT = 1, + DHCP6_ADVERTISE = 2, + DHCP6_REQUEST = 3, + DHCP6_CONFIRM = 4, + DHCP6_RENEW = 5, + DHCP6_REBIND = 6, + DHCP6_REPLY = 7, + DHCP6_RELEASE = 8, + DHCP6_DECLINE = 9, + DHCP6_RECONFIGURE = 10, + DHCP6_INFORMATION_REQUEST = 11, + DHCP6_RELAY_FORW = 12, + DHCP6_RELAY_REPL = 13, + _DHCP6_MESSAGE_MAX = 14, +}; + +enum { + DHCP6_OPTION_CLIENTID = 1, + DHCP6_OPTION_SERVERID = 2, + DHCP6_OPTION_IA_NA = 3, + DHCP6_OPTION_IA_TA = 4, + DHCP6_OPTION_IAADDR = 5, + DHCP6_OPTION_ORO = 6, + DHCP6_OPTION_PREFERENCE = 7, + DHCP6_OPTION_ELAPSED_TIME = 8, + DHCP6_OPTION_RELAY_MSG = 9, + /* option code 10 is unassigned */ + DHCP6_OPTION_AUTH = 11, + DHCP6_OPTION_UNICAST = 12, + DHCP6_OPTION_STATUS_CODE = 13, + DHCP6_OPTION_RAPID_COMMIT = 14, + DHCP6_OPTION_USER_CLASS = 15, + DHCP6_OPTION_VENDOR_CLASS = 16, + DHCP6_OPTION_VENDOR_OPTS = 17, + DHCP6_OPTION_INTERFACE_ID = 18, + DHCP6_OPTION_RECONF_MSG = 19, + DHCP6_OPTION_RECONF_ACCEPT = 20, + + DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */ + DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */ + + DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075 */ + + /* option code 35 is unassigned */ + + DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */ + + /* option codes 89-142 are unassigned */ + /* option codes 144-65535 are unassigned */ +}; + +enum { + DHCP6_STATUS_SUCCESS = 0, + DHCP6_STATUS_UNSPEC_FAIL = 1, + DHCP6_STATUS_NO_ADDRS_AVAIL = 2, + DHCP6_STATUS_NO_BINDING = 3, + DHCP6_STATUS_NOT_ON_LINK = 4, + DHCP6_STATUS_USE_MULTICAST = 5, + _DHCP6_STATUS_MAX = 6, +}; diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c new file mode 100644 index 00000000..b9334bd6 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c @@ -0,0 +1,484 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2013 Tom Gundersen + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include + +#if 0 /* NM_IGNORED */ +#include "strv.h" +#include "siphash24.h" +#include "libudev-private.h" +#endif +#include "dhcp-lease-internal.h" +#if 0 /* NM_IGNORED */ +#include "log.h" +#include "utf8.h" +#endif +#include "util.h" +#if 0 /* NM_IGNORED */ +#include "conf-parser.h" +#include "condition.h" +#endif +#include "network-internal.h" + +#if 0 /* NM_IGNORED */ +const char *net_get_name(struct udev_device *device) { + const char *name, *field; + + assert(device); + + /* fetch some persistent data unique (on this machine) to this device */ + FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") { + name = udev_device_get_property_value(device, field); + if (name) + return name; + } + + return NULL; +} + +#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a) + +int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) { + size_t l, sz = 0; + const char *name = NULL; + int r; + uint8_t *v; + + assert(device); + + name = net_get_name(device); + if (!name) + return -ENOENT; + + l = strlen(name); + sz = sizeof(sd_id128_t) + l; + v = alloca(sz); + + /* fetch some persistent data unique to this machine */ + r = sd_id128_get_machine((sd_id128_t*) v); + if (r < 0) + return r; + memcpy(v + sizeof(sd_id128_t), name, l); + + /* Let's hash the machine ID plus the device name. We + * use a fixed, but originally randomly created hash + * key here. */ + siphash24(result, v, sz, HASH_KEY.bytes); + + return 0; +} + +bool net_match_config(const struct ether_addr *match_mac, + const char *match_path, + const char *match_driver, + const char *match_type, + const char *match_name, + Condition *match_host, + Condition *match_virt, + Condition *match_kernel, + Condition *match_arch, + const struct ether_addr *dev_mac, + const char *dev_path, + const char *dev_parent_driver, + const char *dev_driver, + const char *dev_type, + const char *dev_name) { + + if (match_host && !condition_test(match_host)) + return 0; + + if (match_virt && !condition_test(match_virt)) + return 0; + + if (match_kernel && !condition_test(match_kernel)) + return 0; + + if (match_arch && !condition_test(match_arch)) + return 0; + + if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) + return 0; + + if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0))) + return 0; + + if (match_driver) { + if (dev_parent_driver && !streq(match_driver, dev_parent_driver)) + return 0; + else if (!streq_ptr(match_driver, dev_driver)) + return 0; + } + + if (match_type && !streq_ptr(match_type, dev_type)) + return 0; + + if (match_name && (!dev_name || fnmatch(match_name, dev_name, 0))) + return 0; + + return 1; +} + +int config_parse_net_condition(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) { + + ConditionType cond = ltype; + Condition **ret = data; + bool negate; + Condition *c; + _cleanup_free_ char *s = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + negate = rvalue[0] == '!'; + if (negate) + rvalue++; + + s = strdup(rvalue); + if (!s) + return log_oom(); + + c = condition_new(cond, s, false, negate); + if (!c) + return log_oom(); + + if (*ret) + condition_free(*ret); + + *ret = c; + 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, EINVAL, + "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_ifalias(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; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + n = strdup(rvalue); + if (!n) + return log_oom(); + + if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue); + free(n); + return 0; + } + + free(*s); + if (*n) + *s = n; + else { + free(n); + *s = NULL; + } + + return 0; +} + +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) { + struct ether_addr **hwaddr = data; + struct ether_addr *n; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + n = new0(struct ether_addr, 1); + 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) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Not a valid MAC address, ignoring assignment: %s", rvalue); + free(n); + return 0; + } + + free(*hwaddr); + *hwaddr = n; + + return 0; +} +#endif + +void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) { + unsigned i; + + assert(f); + assert(addresses); + assert(size); + + for (i = 0; i < size; i++) + fprintf(f, "%s%s", inet_ntoa(addresses[i]), + (i < (size - 1)) ? " ": ""); +} + +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; + struct in_addr *new_addresses; + int r; + + 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])); + if (r <= 0) + continue; + + size ++; + } + + *ret = addresses; + addresses = NULL; + + return size; +} + +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; + struct in6_addr *new_addresses; + int r; + + 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])); + if (r <= 0) + continue; + + size++; + } + + *ret = addresses; + addresses = NULL; + + return size; +} + +void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) { + unsigned i; + + assert(f); + assert(key); + assert(routes); + assert(size); + + fprintf(f, "%s=", key); + + for (i = 0; i < size; i++) { + fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr), + routes[i].dst_prefixlen); + fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr), + (i < (size - 1)) ? " ": ""); + } + + fputs("\n", f); +} + +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; + char *tok, *tok_end; + unsigned n; + int r; + + if (!GREEDY_REALLOC(routes, allocated, size + 1)) + return -ENOMEM; + + entry = strndup(word, len); + if(!entry) + return -ENOMEM; + + tok = entry; + + /* get the subnet */ + tok_end = strchr(tok, '/'); + if (!tok_end) + continue; + *tok_end = '\0'; + + r = inet_aton(tok, &routes[size].dst_addr); + if (r == 0) + continue; + + tok = tok_end + 1; + + /* get the prefixlen */ + tok_end = strchr(tok, ','); + if (!tok_end) + continue; + + *tok_end = '\0'; + + r = safe_atou(tok, &n); + if (r < 0 || n > 32) + continue; + + routes[size].dst_prefixlen = (uint8_t) n; + tok = tok_end + 1; + + /* get the gateway */ + r = inet_aton(tok, &routes[size].gw_addr); + if (r == 0) + continue; + + size++; + } + + *ret_size = size; + *ret_allocated = allocated; + *ret = routes; + routes = NULL; + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h new file mode 100644 index 00000000..f87c863d --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h @@ -0,0 +1,78 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Tom Gundersen + + 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 . +***/ + +#include "nm-sd-adapt.h" + +#include +#include +#include + +#if 0 /* NM_IGNORED */ +#include "udev.h" +#include "condition.h" + +bool net_match_config(const struct ether_addr *match_mac, + const char *match_path, + const char *match_driver, + const char *match_type, + const char *match_name, + Condition *match_host, + Condition *match_virt, + Condition *match_kernel, + Condition *match_arch, + const struct ether_addr *dev_mac, + const char *dev_path, + const char *dev_parent_driver, + const char *dev_driver, + const char *dev_type, + const char *dev_name); + +int config_parse_net_condition(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_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_ifalias(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 net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]); +const char *net_get_name(struct udev_device *device); +#endif + +void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size); +int deserialize_in_addrs(struct in_addr **addresses, const char *string); +int deserialize_in6_addrs(struct in6_addr **addresses, const char *string); + +/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */ +struct sd_dhcp_route; + +void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size); +int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string); diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c new file mode 100644 index 00000000..3e4cd8d9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c @@ -0,0 +1,1726 @@ +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "list.h" +#include "refcnt.h" +#include "async.h" + +#include "dhcp-protocol.h" +#include "dhcp-internal.h" +#include "dhcp-lease-internal.h" +#include "sd-dhcp-client.h" + +#define MAX_CLIENT_ID_LEN 64 /* Arbitrary limit */ +#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN + +struct sd_dhcp_client { + RefCount n_ref; + + DHCPState state; + sd_event *event; + int event_priority; + sd_event_source *timeout_resend; + int index; + int fd; + union sockaddr_union link; + sd_event_source *receive_message; + bool request_broadcast; + uint8_t *req_opts; + size_t req_opts_allocated; + size_t req_opts_size; + be32_t last_addr; + uint8_t mac_addr[MAX_MAC_ADDR_LEN]; + size_t mac_addr_len; + uint16_t arp_type; + union { + struct { + uint8_t type; /* 0: Generic (non-LL) (RFC 2132) */ + uint8_t data[MAX_CLIENT_ID_LEN]; + } _packed_ gen; + struct { + uint8_t type; /* 1: Ethernet Link-Layer (RFC 2132) */ + uint8_t haddr[ETH_ALEN]; + } _packed_ eth; + struct { + uint8_t type; /* 2 - 254: ARP/Link-Layer (RFC 2132) */ + uint8_t haddr[0]; + } _packed_ ll; + struct { + uint8_t type; /* 255: Node-specific (RFC 4361) */ + uint8_t iaid[4]; + uint8_t duid[MAX_CLIENT_ID_LEN - 4]; + } _packed_ ns; + struct { + uint8_t type; + uint8_t data[MAX_CLIENT_ID_LEN]; + } _packed_ raw; + } client_id; + size_t client_id_len; + char *hostname; + char *vendor_class_identifier; + uint32_t mtu; + uint32_t xid; + usec_t start_time; + unsigned int attempt; + usec_t request_sent; + sd_event_source *timeout_t1; + sd_event_source *timeout_t2; + sd_event_source *timeout_expire; + sd_dhcp_client_cb_t cb; + void *userdata; + sd_dhcp_lease *lease; +}; + +static const uint8_t default_req_opts[] = { + DHCP_OPTION_SUBNET_MASK, + DHCP_OPTION_ROUTER, + DHCP_OPTION_HOST_NAME, + DHCP_OPTION_DOMAIN_NAME, + DHCP_OPTION_DOMAIN_NAME_SERVER, + DHCP_OPTION_NTP_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 void client_stop(sd_dhcp_client *client, int error); + +int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb, + void *userdata) { + assert_return(client, -EINVAL); + + client->cb = cb; + client->userdata = userdata; + + return 0; +} + +int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) { + assert_return(client, -EINVAL); + + client->request_broadcast = !!broadcast; + + return 0; +} + +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); + + switch(option) { + case DHCP_OPTION_PAD: + case DHCP_OPTION_OVERLOAD: + case DHCP_OPTION_MESSAGE_TYPE: + case DHCP_OPTION_PARAMETER_REQUEST_LIST: + case DHCP_OPTION_END: + return -EINVAL; + + default: + break; + } + + for (i = 0; i < client->req_opts_size; i++) + if (client->req_opts[i] == option) + return -EEXIST; + + if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated, + client->req_opts_size + 1)) + return -ENOMEM; + + client->req_opts[client->req_opts_size++] = option; + + return 0; +} + +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); + + if (last_addr) + client->last_addr = last_addr->s_addr; + else + client->last_addr = INADDR_ANY; + + 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); + + client->index = interface_index; + + return 0; +} + +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; + + assert_return(client, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL); + assert_return(arp_type > 0, -EINVAL); + + if (arp_type == ARPHRD_ETHER) + assert_return(addr_len == ETH_ALEN, -EINVAL); + else if (arp_type == ARPHRD_INFINIBAND) + assert_return(addr_len == INFINIBAND_ALEN, -EINVAL); + else + return -EINVAL; + + if (client->mac_addr_len == addr_len && + memcmp(&client->mac_addr, addr, addr_len) == 0) + 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"); + need_restart = true; + client_stop(client, DHCP_EVENT_STOP); + } + + memcpy(&client->mac_addr, addr, addr_len); + client->mac_addr_len = addr_len; + client->arp_type = arp_type; + + if (need_restart && client->state != DHCP_STATE_STOPPED) + sd_dhcp_client_start(client); + + return 0; +} + +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); + assert_return(data, -EINVAL); + assert_return(data_len, -EINVAL); + + *type = 0; + *data = NULL; + *data_len = 0; + if (client->client_id_len) { + *type = client->client_id.raw.type; + *data = client->client_id.raw.data; + *data_len = client->client_id_len - + sizeof (client->client_id.raw.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) { + DHCP_CLIENT_DONT_DESTROY(client); + bool need_restart = false; + + assert_return(client, -EINVAL); + assert_return(data, -EINVAL); + 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; + } + + if (client->client_id_len == data_len + sizeof (client->client_id.raw.type) && + client->client_id.raw.type == type && + memcmp(&client->client_id.raw.data, data, data_len) == 0) + return 0; + + if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { + log_dhcp_client(client, "Changing client ID on running DHCP " + "client, restarting"); + need_restart = true; + client_stop(client, DHCP_EVENT_STOP); + } + + client->client_id.raw.type = type; + memcpy(&client->client_id.raw.data, data, data_len); + client->client_id_len = data_len + sizeof (client->client_id.raw.type); + + if (need_restart && client->state != DHCP_STATE_STOPPED) + sd_dhcp_client_start(client); + + return 0; +} + +int sd_dhcp_client_set_hostname(sd_dhcp_client *client, + const char *hostname) { + char *new_hostname = NULL; + + assert_return(client, -EINVAL); + + if (streq_ptr(client->hostname, hostname)) + return 0; + + if (hostname) { + new_hostname = strdup(hostname); + if (!new_hostname) + return -ENOMEM; + } + + free(client->hostname); + client->hostname = new_hostname; + + return 0; +} + +int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, + const char *vci) { + char *new_vci = NULL; + + assert_return(client, -EINVAL); + + new_vci = strdup(vci); + if (!new_vci) + return -ENOMEM; + + free(client->vendor_class_identifier); + + client->vendor_class_identifier = new_vci; + + return 0; +} + +int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) { + assert_return(client, -EINVAL); + assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE); + + client->mtu = mtu; + + return 0; +} + +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 = sd_dhcp_lease_ref(client->lease); + + return 0; +} + +static void client_notify(sd_dhcp_client *client, int event) { + if (client->cb) + client->cb(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->fd = asynchronous_close(client->fd); + + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + client->timeout_expire = sd_event_source_unref(client->timeout_expire); + + client->attempt = 1; + + client->state = DHCP_STATE_INIT; + client->xid = 0; + + if (client->lease) + client->lease = sd_dhcp_lease_unref(client->lease); + + return 0; +} + +static void client_stop(sd_dhcp_client *client, int error) { + assert(client); + + if (error < 0) + log_dhcp_client(client, "STOPPED: %s", strerror(-error)); + else if (error == DHCP_EVENT_STOP) + log_dhcp_client(client, "STOPPED"); + else + log_dhcp_client(client, "STOPPED: Unknown event"); + + client_notify(client, error); + + client_initialize(client); +} + +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; + usec_t time_now; + uint16_t secs; + int r; + + assert(client); + assert(client->start_time); + assert(ret); + assert(_optlen); + assert(_optoffset); + assert(type == DHCP_DISCOVER || type == DHCP_REQUEST); + + /* See RFC2131 section 4.4.1 */ + + optlen = DHCP_MIN_OPTIONS_SIZE; + size = sizeof(DHCPPacket) + optlen; + + packet = malloc0(size); + if (!packet) + return -ENOMEM; + + r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type, + client->arp_type, optlen, &optoffset); + if (r < 0) + return r; + + /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers + refuse to issue an DHCP lease if 'secs' is set to zero */ + r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + assert(time_now >= client->start_time); + + /* seconds between sending first and last DISCOVER + * must always be strictly positive to deal with broken servers */ + secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1; + packet->dhcp.secs = htobe16(secs); + + /* RFC2132 section 4.1 + A client that cannot receive unicast IP datagrams until its protocol + software has been configured with an IP address SHOULD set the + BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or + DHCPREQUEST messages that client sends. The BROADCAST bit will + provide a hint to the DHCP server and BOOTP relay agent to broadcast + any messages to the client on the client's subnet. + + Note: some interfaces needs this to be enabled, but some networks + needs this to be disabled as broadcasts are filteretd, so this + needs to be configurable */ + if (client->request_broadcast || client->arp_type != ARPHRD_ETHER) + packet->dhcp.flags = htobe16(0x8000); + + /* RFC2132 section 4.1.1: + The client MUST include its hardware address in the ’chaddr’ field, if + necessary for delivery of DHCP reply messages. Non-Ethernet + interfaces will leave 'chaddr' empty and use the client identifier + instead (eg, RFC 4390 section 2.1). + */ + if (client->arp_type == ARPHRD_ETHER) + memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN); + + /* If no client identifier exists, construct one from an ethernet + address if present */ + if (client->client_id_len == 0 && client->arp_type == ARPHRD_ETHER) { + client->client_id.eth.type = ARPHRD_ETHER; + memcpy(&client->client_id.eth.haddr, &client->mac_addr, ETH_ALEN); + client->client_id_len = sizeof (client->client_id.eth); + } + + /* Some DHCP servers will refuse to issue an DHCP lease if the Client + Identifier option is not set */ + if (client->client_id_len) { + r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_CLIENT_IDENTIFIER, + client->client_id_len, + &client->client_id.raw); + if (r < 0) + return r; + } + + /* RFC2131 section 3.5: + in its initial DHCPDISCOVER or DHCPREQUEST message, a + client may provide the server with a list of specific + parameters the client is interested in. If the client + includes a list of parameters in a DHCPDISCOVER message, + it MUST include that list in any subsequent DHCPREQUEST + messages. + */ + r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_PARAMETER_REQUEST_LIST, + client->req_opts_size, client->req_opts); + if (r < 0) + return r; + + /* RFC2131 section 3.5: + The client SHOULD include the ’maximum DHCP message size’ option to + let the server know how large the server may make its DHCP messages. + + Note (from ConnMan): Some DHCP servers will send bigger DHCP packets + than the defined default size unless the Maximum Messge Size option + is explicitely set + + RFC3442 "Requirements to Avoid Sizing Constraints": + Because a full routing table can be quite large, the standard 576 + octet maximum size for a DHCP message may be too short to contain + some legitimate Classless Static Route options. Because of this, + clients implementing the Classless Static Route option SHOULD send a + Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP + stack is capable of receiving larger IP datagrams. In this case, the + client SHOULD set the value of this option to at least the MTU of the + interface that the client is configuring. The client MAY set the + value of this option higher, up to the size of the largest UDP packet + it is prepared to accept. (Note that the value specified in the + Maximum DHCP Message Size option is the total maximum packet size, + including IP and UDP headers.) + */ + max_size = htobe16(size); + r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0, + DHCP_OPTION_MAXIMUM_MESSAGE_SIZE, + 2, &max_size); + if (r < 0) + return r; + + *_optlen = optlen; + *_optoffset = optoffset; + *ret = packet; + packet = NULL; + + return 0; +} + +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); + + return dhcp_network_send_raw_socket(client->fd, &client->link, + packet, len); +} + +static int client_send_discover(sd_dhcp_client *client) { + _cleanup_free_ DHCPPacket *discover = NULL; + size_t optoffset, optlen; + int r; + + assert(client); + assert(client->state == DHCP_STATE_INIT || + client->state == DHCP_STATE_SELECTING); + + r = client_message_init(client, &discover, DHCP_DISCOVER, + &optlen, &optoffset); + if (r < 0) + return r; + + /* the client may suggest values for the network address + and lease time in the DHCPDISCOVER message. The client may include + the ’requested IP address’ option to suggest that a particular IP + address be assigned, and may include the ’IP address lease time’ + option to suggest the lease time it would like. + */ + if (client->last_addr != INADDR_ANY) { + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_REQUESTED_IP_ADDRESS, + 4, &client->last_addr); + if (r < 0) + return r; + } + + /* it is unclear from RFC 2131 if client should send hostname in + DHCPDISCOVER but dhclient does and so we do as well + */ + if (client->hostname) { + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_HOST_NAME, + strlen(client->hostname), client->hostname); + if (r < 0) + return r; + } + + if (client->vendor_class_identifier) { + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_VENDOR_CLASS_IDENTIFIER, + strlen(client->vendor_class_identifier), + client->vendor_class_identifier); + if (r < 0) + return r; + } + + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_END, 0, NULL); + if (r < 0) + return r; + + /* We currently ignore: + The client SHOULD wait a random time between one and ten seconds to + desynchronize the use of DHCP at startup. + */ + r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset); + if (r < 0) + return r; + + log_dhcp_client(client, "DISCOVER"); + + return 0; +} + +static int client_send_request(sd_dhcp_client *client) { + _cleanup_free_ DHCPPacket *request = NULL; + size_t optoffset, optlen; + int r; + + r = client_message_init(client, &request, DHCP_REQUEST, + &optlen, &optoffset); + if (r < 0) + return r; + + switch (client->state) { + /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC, + SELECTING should be REQUESTING) + */ + + case DHCP_STATE_REQUESTING: + /* Client inserts the address of the selected server in ’server + identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be + filled in with the yiaddr value from the chosen DHCPOFFER. + */ + + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_SERVER_IDENTIFIER, + 4, &client->lease->server_address); + if (r < 0) + return r; + + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_REQUESTED_IP_ADDRESS, + 4, &client->lease->address); + if (r < 0) + return r; + + break; + + case DHCP_STATE_INIT_REBOOT: + /* ’server identifier’ MUST NOT be filled in, ’requested IP address’ + option MUST be filled in with client’s notion of its previously + assigned address. ’ciaddr’ MUST be zero. + */ + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_REQUESTED_IP_ADDRESS, + 4, &client->last_addr); + if (r < 0) + return r; + break; + + case DHCP_STATE_RENEWING: + /* ’server identifier’ MUST NOT be filled in, ’requested IP address’ + option MUST NOT be filled in, ’ciaddr’ MUST be filled in with + client’s IP address. + */ + + /* fall through */ + case DHCP_STATE_REBINDING: + /* ’server identifier’ MUST NOT be filled in, ’requested IP address’ + option MUST NOT be filled in, ’ciaddr’ MUST be filled in with + client’s IP address. + + This message MUST be broadcast to the 0xffffffff IP broadcast address. + */ + request->dhcp.ciaddr = client->lease->address; + + break; + + case DHCP_STATE_INIT: + case DHCP_STATE_SELECTING: + case DHCP_STATE_REBOOTING: + case DHCP_STATE_BOUND: + case DHCP_STATE_STOPPED: + return -EINVAL; + } + + if (client->hostname) { + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_HOST_NAME, + strlen(client->hostname), client->hostname); + if (r < 0) + return r; + } + + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + DHCP_OPTION_END, 0, NULL); + if (r < 0) + return r; + + if (client->state == DHCP_STATE_RENEWING) { + r = dhcp_network_send_udp_socket(client->fd, + client->lease->server_address, + DHCP_PORT_SERVER, + &request->dhcp, + sizeof(DHCPMessage) + optoffset); + } else { + r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset); + } + if (r < 0) + 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; + } + + return 0; +} + +static int client_start(sd_dhcp_client *client); + +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; + uint64_t time_now; + uint32_t time_left; + int r; + + assert(s); + assert(client); + assert(client->event); + + r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + goto error; + + switch (client->state) { + case DHCP_STATE_RENEWING: + + time_left = (client->lease->t2 - client->lease->t1) / 2; + if (time_left < 60) + time_left = 60; + + next_timeout = time_now + time_left * USEC_PER_SEC; + + break; + + case DHCP_STATE_REBINDING: + + time_left = (client->lease->lifetime - client->lease->t2) / 2; + if (time_left < 60) + time_left = 60; + + next_timeout = time_now + time_left * USEC_PER_SEC; + break; + + case DHCP_STATE_REBOOTING: + /* start over as we did not receive a timely ack or nak */ + r = client_initialize(client); + if (r < 0) + goto error; + + r = client_start(client); + if (r < 0) + goto error; + else { + log_dhcp_client(client, "REBOOTED"); + return 0; + } + + case DHCP_STATE_INIT: + case DHCP_STATE_INIT_REBOOT: + case DHCP_STATE_SELECTING: + case DHCP_STATE_REQUESTING: + case DHCP_STATE_BOUND: + + if (client->attempt < 64) + client->attempt *= 2; + + next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC; + + break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; + } + + next_timeout += (random_u32() & 0x1fffff); + + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + + r = sd_event_add_time(client->event, + &client->timeout_resend, + clock_boottime_or_monotonic(), + next_timeout, 10 * USEC_PER_MSEC, + client_timeout_resend, client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); + if (r < 0) + goto error; + + switch (client->state) { + case DHCP_STATE_INIT: + r = client_send_discover(client); + if (r >= 0) { + client->state = DHCP_STATE_SELECTING; + client->attempt = 1; + } else { + if (client->attempt >= 64) + goto error; + } + + break; + + case DHCP_STATE_SELECTING: + r = client_send_discover(client); + if (r < 0 && client->attempt >= 64) + goto error; + + break; + + case DHCP_STATE_INIT_REBOOT: + case DHCP_STATE_REQUESTING: + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + r = client_send_request(client); + if (r < 0 && client->attempt >= 64) + goto error; + + if (client->state == DHCP_STATE_INIT_REBOOT) + client->state = DHCP_STATE_REBOOTING; + + client->request_sent = time_now; + + break; + + case DHCP_STATE_REBOOTING: + case DHCP_STATE_BOUND: + + break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; + } + + return 0; + +error: + client_stop(client, r); + + /* Errors were dealt with when stopping the client, don't spill + errors into the event loop handler */ + return 0; +} + +static int client_initialize_io_events(sd_dhcp_client *client, + sd_event_io_handler_t io_callback) { + int r; + + assert(client); + assert(client->event); + + r = sd_event_add_io(client->event, &client->receive_message, + client->fd, EPOLLIN, io_callback, + client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->receive_message, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message"); + if (r < 0) + goto error; + +error: + if (r < 0) + client_stop(client, r); + + return 0; +} + +static int client_initialize_time_events(sd_dhcp_client *client) { + int r; + + assert(client); + assert(client->event); + + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + + r = sd_event_add_time(client->event, + &client->timeout_resend, + clock_boottime_or_monotonic(), + 0, 0, + client_timeout_resend, client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, + client->event_priority); + + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); + if (r < 0) + goto error; + +error: + if (r < 0) + client_stop(client, r); + + return 0; + +} + +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); + + return 0; +} + +static int client_start(sd_dhcp_client *client) { + int r; + + assert_return(client, -EINVAL); + assert_return(client->event, -EINVAL); + assert_return(client->index > 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); + + client->xid = random_u32(); + + r = dhcp_network_bind_raw_socket(client->index, &client->link, + client->xid, client->mac_addr, + client->mac_addr_len, client->arp_type); + if (r < 0) { + client_stop(client, r); + return r; + } + client->fd = r; + + if (client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT) + client->start_time = now(clock_boottime_or_monotonic()); + + return client_initialize_events(client, client_receive_message_raw); +} + +static int client_timeout_expire(sd_event_source *s, uint64_t usec, + void *userdata) { + sd_dhcp_client *client = userdata; + DHCP_CLIENT_DONT_DESTROY(client); + + log_dhcp_client(client, "EXPIRED"); + + client_notify(client, DHCP_EVENT_EXPIRED); + + /* lease was lost, start over if not freed or stopped in callback */ + if (client->state != DHCP_STATE_STOPPED) { + client_initialize(client); + client_start(client); + } + + return 0; +} + +static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) { + sd_dhcp_client *client = userdata; + DHCP_CLIENT_DONT_DESTROY(client); + int r; + + 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, + client->xid, client->mac_addr, + client->mac_addr_len, client->arp_type); + if (r < 0) { + client_stop(client, r); + return 0; + } + client->fd = r; + + return client_initialize_events(client, client_receive_message_raw); +} + +static int client_timeout_t1(sd_event_source *s, uint64_t usec, + void *userdata) { + sd_dhcp_client *client = userdata; + DHCP_CLIENT_DONT_DESTROY(client); + + client->state = DHCP_STATE_RENEWING; + client->attempt = 1; + + return client_initialize_time_events(client); +} + +static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, + size_t len) { + _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; + int r; + + r = dhcp_lease_new(&lease); + if (r < 0) + return r; + + if (client->client_id_len) { + r = dhcp_lease_set_client_id(lease, + (uint8_t *) &client->client_id.raw, + client->client_id_len); + if (r < 0) + return r; + } + + r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease); + if (r != DHCP_OFFER) { + log_dhcp_client(client, "received message was not an OFFER, ignoring"); + return -ENOMSG; + } + + lease->next_server = offer->siaddr; + + lease->address = offer->yiaddr; + + if (lease->address == INADDR_ANY || + lease->server_address == INADDR_ANY || + lease->lifetime == 0) { + log_dhcp_client(client, "received lease lacks address, server " + "address or lease lifetime, ignoring"); + return -ENOMSG; + } + + if (lease->subnet_mask == INADDR_ANY) { + r = dhcp_lease_set_default_subnet_mask(lease); + if (r < 0) { + log_dhcp_client(client, "received lease lacks subnet " + "mask, and a fallback one can not be " + "generated, ignoring"); + return -ENOMSG; + } + } + + sd_dhcp_lease_unref(client->lease); + client->lease = lease; + lease = NULL; + + log_dhcp_client(client, "OFFER"); + + return 0; +} + +static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, + size_t len) { + int r; + + r = dhcp_option_parse(force, len, NULL, NULL); + if (r != DHCP_FORCERENEW) + return -ENOMSG; + + log_dhcp_client(client, "FORCERENEW"); + + return 0; +} + +static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, + size_t len) { + _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; + int r; + + r = dhcp_lease_new(&lease); + if (r < 0) + return r; + + if (client->client_id_len) { + r = dhcp_lease_set_client_id(lease, + (uint8_t *) &client->client_id.raw, + client->client_id_len); + if (r < 0) + return r; + } + + r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease); + if (r == DHCP_NAK) { + log_dhcp_client(client, "NAK"); + return -EADDRNOTAVAIL; + } + + if (r != DHCP_ACK) { + log_dhcp_client(client, "received message was not an ACK, ignoring"); + return -ENOMSG; + } + + lease->next_server = ack->siaddr; + + lease->address = ack->yiaddr; + + if (lease->address == INADDR_ANY || + lease->server_address == INADDR_ANY || + lease->lifetime == 0) { + log_dhcp_client(client, "received lease lacks address, server " + "address or lease lifetime, ignoring"); + return -ENOMSG; + } + + if (lease->subnet_mask == INADDR_ANY) { + r = dhcp_lease_set_default_subnet_mask(lease); + if (r < 0) { + log_dhcp_client(client, "received lease lacks subnet " + "mask, and a fallback one can not be " + "generated, ignoring"); + return -ENOMSG; + } + } + + r = DHCP_EVENT_IP_ACQUIRE; + if (client->lease) { + if (client->lease->address != lease->address || + client->lease->subnet_mask != lease->subnet_mask || + client->lease->router != lease->router) { + r = DHCP_EVENT_IP_CHANGE; + } else + r = DHCP_EVENT_RENEW; + + client->lease = sd_dhcp_lease_unref(client->lease); + } + + client->lease = lease; + lease = NULL; + + log_dhcp_client(client, "ACK"); + + return r; +} + +static uint64_t client_compute_timeout(sd_dhcp_client *client, + uint32_t lifetime, double factor) { + assert(client); + assert(client->request_sent); + assert(lifetime); + + return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) + + + (random_u32() & 0x1fffff); +} + +static int client_set_lease_timeouts(sd_dhcp_client *client) { + usec_t time_now; + uint64_t lifetime_timeout; + uint64_t t2_timeout; + uint64_t t1_timeout; + char time_string[FORMAT_TIMESPAN_MAX]; + int r; + + assert(client); + assert(client->event); + assert(client->lease); + assert(client->lease->lifetime); + + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + client->timeout_expire = sd_event_source_unref(client->timeout_expire); + + /* don't set timers for infinite leases */ + if (client->lease->lifetime == 0xffffffff) + return 0; + + r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + return r; + assert(client->request_sent <= time_now); + + /* convert the various timeouts from relative (secs) to absolute (usecs) */ + lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1); + if (client->lease->t1 && client->lease->t2) { + /* both T1 and T2 are given */ + if (client->lease->t1 < client->lease->t2 && + client->lease->t2 < client->lease->lifetime) { + /* they are both valid */ + t2_timeout = client_compute_timeout(client, client->lease->t2, 1); + t1_timeout = client_compute_timeout(client, client->lease->t1, 1); + } else { + /* discard both */ + t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); + client->lease->t2 = (client->lease->lifetime * 7) / 8; + t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); + client->lease->t1 = client->lease->lifetime / 2; + } + } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) { + /* only T2 is given, and it is valid */ + t2_timeout = client_compute_timeout(client, client->lease->t2, 1); + t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); + client->lease->t1 = client->lease->lifetime / 2; + if (t2_timeout <= t1_timeout) { + /* the computed T1 would be invalid, so discard T2 */ + t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); + client->lease->t2 = (client->lease->lifetime * 7) / 8; + } + } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) { + /* only T1 is given, and it is valid */ + t1_timeout = client_compute_timeout(client, client->lease->t1, 1); + t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); + client->lease->t2 = (client->lease->lifetime * 7) / 8; + if (t2_timeout <= t1_timeout) { + /* the computed T2 would be invalid, so discard T1 */ + t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); + client->lease->t2 = client->lease->lifetime / 2; + } + } else { + /* fall back to the default timeouts */ + t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5); + client->lease->t1 = client->lease->lifetime / 2; + t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0); + client->lease->t2 = (client->lease->lifetime * 7) / 8; + } + + /* arm lifetime timeout */ + r = sd_event_add_time(client->event, &client->timeout_expire, + clock_boottime_or_monotonic(), + lifetime_timeout, 10 * USEC_PER_MSEC, + client_timeout_expire, client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->timeout_expire, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime"); + if (r < 0) + return r; + + log_dhcp_client(client, "lease expires in %s", + format_timespan(time_string, FORMAT_TIMESPAN_MAX, + lifetime_timeout - time_now, 0)); + + /* don't arm earlier timeouts if this has already expired */ + if (lifetime_timeout <= time_now) + return 0; + + /* arm T2 timeout */ + r = sd_event_add_time(client->event, + &client->timeout_t2, + clock_boottime_or_monotonic(), + t2_timeout, + 10 * USEC_PER_MSEC, + client_timeout_t2, client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->timeout_t2, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout"); + if (r < 0) + return r; + + log_dhcp_client(client, "T2 expires in %s", + format_timespan(time_string, FORMAT_TIMESPAN_MAX, + t2_timeout - time_now, 0)); + + /* don't arm earlier timeout if this has already expired */ + if (t2_timeout <= time_now) + return 0; + + /* arm T1 timeout */ + r = sd_event_add_time(client->event, + &client->timeout_t1, + clock_boottime_or_monotonic(), + t1_timeout, 10 * USEC_PER_MSEC, + client_timeout_t1, client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->timeout_t1, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer"); + if (r < 0) + return r; + + log_dhcp_client(client, "T1 expires in %s", + format_timespan(time_string, FORMAT_TIMESPAN_MAX, + t1_timeout - time_now, 0)); + + return 0; +} + +static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, + int len) { + DHCP_CLIENT_DONT_DESTROY(client); + int r = 0, notify_event = 0; + + assert(client); + assert(client->event); + assert(message); + + switch (client->state) { + case DHCP_STATE_SELECTING: + + r = client_handle_offer(client, message, len); + if (r >= 0) { + + client->timeout_resend = + sd_event_source_unref(client->timeout_resend); + + client->state = DHCP_STATE_REQUESTING; + client->attempt = 1; + + r = sd_event_add_time(client->event, + &client->timeout_resend, + clock_boottime_or_monotonic(), + 0, 0, + client_timeout_resend, client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); + if (r < 0) + goto error; + } else if (r == -ENOMSG) + /* invalid message, let's ignore it */ + return 0; + + break; + + case DHCP_STATE_REBOOTING: + case DHCP_STATE_REQUESTING: + case DHCP_STATE_RENEWING: + case DHCP_STATE_REBINDING: + + r = client_handle_ack(client, message, len); + if (r >= 0) { + client->timeout_resend = + sd_event_source_unref(client->timeout_resend); + client->receive_message = + sd_event_source_unref(client->receive_message); + client->fd = asynchronous_close(client->fd); + + if (IN_SET(client->state, DHCP_STATE_REQUESTING, + DHCP_STATE_REBOOTING)) + notify_event = DHCP_EVENT_IP_ACQUIRE; + else if (r != DHCP_EVENT_IP_ACQUIRE) + notify_event = r; + + client->state = DHCP_STATE_BOUND; + client->attempt = 1; + + client->last_addr = client->lease->address; + + r = client_set_lease_timeouts(client); + if (r < 0) + goto error; + + r = dhcp_network_bind_udp_socket(client->lease->address, + DHCP_PORT_CLIENT); + if (r < 0) { + log_dhcp_client(client, "could not bind UDP socket"); + goto error; + } + + client->fd = r; + + client_initialize_io_events(client, client_receive_message_udp); + + if (notify_event) { + client_notify(client, notify_event); + if (client->state == DHCP_STATE_STOPPED) + return 0; + } + + } else if (r == -EADDRNOTAVAIL) { + /* got a NAK, let's restart the client */ + client->timeout_resend = + sd_event_source_unref(client->timeout_resend); + + r = client_initialize(client); + if (r < 0) + goto error; + + r = client_start(client); + if (r < 0) + goto error; + + log_dhcp_client(client, "REBOOTED"); + + return 0; + } else if (r == -ENOMSG) + /* invalid message, let's ignore it */ + return 0; + + break; + + case DHCP_STATE_BOUND: + r = client_handle_forcerenew(client, message, len); + if (r >= 0) { + r = client_timeout_t1(NULL, 0, client); + if (r < 0) + goto error; + } else if (r == -ENOMSG) + /* invalid message, let's ignore it */ + return 0; + + break; + + case DHCP_STATE_INIT: + case DHCP_STATE_INIT_REBOOT: + + break; + + case DHCP_STATE_STOPPED: + r = -EINVAL; + goto error; + } + +error: + if (r < 0) + client_stop(client, r); + + return r; +} + +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; + int buflen = 0, len, r; + const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } }; + const struct ether_addr *expected_chaddr = NULL; + uint8_t expected_hlen = 0; + + assert(s); + assert(client); + + r = ioctl(fd, FIONREAD, &buflen); + if (r < 0) + return r; + + if (buflen < 0) + /* this can't be right */ + return -EIO; + + message = malloc0(buflen); + if (!message) + return -ENOMEM; + + len = read(fd, message, buflen); + if (len < 0) { + log_dhcp_client(client, "could not receive message from UDP " + "socket: %m"); + return 0; + } else if ((size_t)len < sizeof(DHCPMessage)) { + log_dhcp_client(client, "too small to be a DHCP message: ignoring"); + return 0; + } + + if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) { + log_dhcp_client(client, "not a DHCP message: ignoring"); + return 0; + } + + if (message->op != BOOTREPLY) { + log_dhcp_client(client, "not a BOOTREPLY message: ignoring"); + return 0; + } + + if (message->htype != client->arp_type) { + log_dhcp_client(client, "packet type does not match client type"); + return 0; + } + + if (client->arp_type == ARPHRD_ETHER) { + expected_hlen = ETH_ALEN; + expected_chaddr = (const struct ether_addr *) &client->mac_addr; + } else { + /* Non-ethernet links expect zero chaddr */ + expected_hlen = 0; + expected_chaddr = &zero_mac; + } + + if (message->hlen != expected_hlen) { + log_dhcp_client(client, "unexpected packet hlen %d", message->hlen); + return 0; + } + + if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) { + log_dhcp_client(client, "received chaddr does not match " + "expected: ignoring"); + return 0; + } + + if (client->state != DHCP_STATE_BOUND && + be32toh(message->xid) != client->xid) { + /* in BOUND state, we may receive FORCERENEW with xid set by server, + so ignore the xid in this case */ + log_dhcp_client(client, "received xid (%u) does not match " + "expected (%u): ignoring", + be32toh(message->xid), client->xid); + return 0; + } + + return client_handle_message(client, message, len); +} + +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))]; + struct iovec iov = {}; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = cmsgbuf, + .msg_controllen = sizeof(cmsgbuf), + }; + struct cmsghdr *cmsg; + bool checksum = true; + int buflen = 0, len, r; + + assert(s); + assert(client); + + r = ioctl(fd, FIONREAD, &buflen); + if (r < 0) + return r; + + if (buflen < 0) + /* this can't be right */ + return -EIO; + + packet = malloc0(buflen); + if (!packet) + return -ENOMEM; + + iov.iov_base = packet; + iov.iov_len = buflen; + + len = recvmsg(fd, &msg, 0); + if (len < 0) { + log_dhcp_client(client, "could not receive message from raw " + "socket: %m"); + return 0; + } else if ((size_t)len < sizeof(DHCPPacket)) + return 0; + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_PACKET && + cmsg->cmsg_type == PACKET_AUXDATA && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) { + struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg); + + checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY); + break; + } + } + + r = dhcp_packet_verify_headers(packet, len, checksum); + if (r < 0) + return 0; + + len -= DHCP_IP_UDP_SIZE; + + return client_handle_message(client, &packet->dhcp, len); +} + +int sd_dhcp_client_start(sd_dhcp_client *client) { + int r; + + assert_return(client, -EINVAL); + + r = client_initialize(client); + if (r < 0) + return r; + + if (client->last_addr) + client->state = DHCP_STATE_INIT_REBOOT; + + r = client_start(client); + if (r >= 0) + log_dhcp_client(client, "STARTED on ifindex %u", client->index); + + return r; +} + +int sd_dhcp_client_stop(sd_dhcp_client *client) { + DHCP_CLIENT_DONT_DESTROY(client); + + assert_return(client, -EINVAL); + + client_stop(client, DHCP_EVENT_STOP); + client->state = DHCP_STATE_STOPPED; + + return 0; +} + +int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, + int priority) { + int r; + + assert_return(client, -EINVAL); + assert_return(!client->event, -EBUSY); + + if (event) + client->event = sd_event_ref(event); + else { + r = sd_event_default(&client->event); + if (r < 0) + return 0; + } + + client->event_priority = priority; + + return 0; +} + +int sd_dhcp_client_detach_event(sd_dhcp_client *client) { + assert_return(client, -EINVAL); + + client->event = sd_event_unref(client->event); + + return 0; +} + +sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) { + if (!client) + return NULL; + + return client->event; +} + +sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) { + if (client) + assert_se(REFCNT_INC(client->n_ref) >= 2); + + return client; +} + +sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { + if (client && REFCNT_DEC(client->n_ref) <= 0) { + log_dhcp_client(client, "FREE"); + + client_initialize(client); + + client->receive_message = + sd_event_source_unref(client->receive_message); + + sd_dhcp_client_detach_event(client); + + sd_dhcp_lease_unref(client->lease); + + free(client->req_opts); + free(client->hostname); + free(client->vendor_class_identifier); + free(client); + } + + return NULL; +} + +int sd_dhcp_client_new(sd_dhcp_client **ret) { + _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL; + + assert_return(ret, -EINVAL); + + client = new0(sd_dhcp_client, 1); + if (!client) + return -ENOMEM; + + client->n_ref = REFCNT_INIT; + client->state = DHCP_STATE_INIT; + client->index = -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; + + *ret = client; + client = NULL; + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c new file mode 100644 index 00000000..2d13d503 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c @@ -0,0 +1,865 @@ +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "list.h" +#if 0 /* NM_IGNORED */ +#include "mkdir.h" +#endif +#include "fileio.h" +#include "unaligned.h" +#include "in-addr-util.h" + +#include "dhcp-protocol.h" +#include "dhcp-internal.h" +#include "dhcp-lease-internal.h" +#include "sd-dhcp-lease.h" +#include "sd-dhcp-client.h" +#include "network-internal.h" + +int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->address; + + return 0; +} + +int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) { + assert_return(lease, -EINVAL); + assert_return(lease, -EINVAL); + + *lifetime = lease->lifetime; + + return 0; +} + +int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) { + assert_return(lease, -EINVAL); + assert_return(mtu, -EINVAL); + + if (lease->mtu) + *mtu = lease->mtu; + else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->dns_size) { + *addr = lease->dns; + return lease->dns_size; + } else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->ntp_size) { + *addr = lease->ntp; + return lease->ntp_size; + } else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { + assert_return(lease, -EINVAL); + assert_return(domainname, -EINVAL); + + if (lease->domainname) + *domainname = lease->domainname; + else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) { + assert_return(lease, -EINVAL); + assert_return(hostname, -EINVAL); + + if (lease->hostname) + *hostname = lease->hostname; + else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) { + assert_return(lease, -EINVAL); + assert_return(root_path, -EINVAL); + + if (lease->root_path) + *root_path = lease->root_path; + else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->router != INADDR_ANY) + addr->s_addr = lease->router; + else + return -ENOENT; + + return 0; +} + +int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->subnet_mask; + + return 0; +} + +int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->server_address; + + return 0; +} + +int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + addr->s_addr = lease->next_server; + + return 0; +} + +int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) { + + assert_return(lease, -EINVAL); + assert_return(routes, -EINVAL); + + if (lease->static_route_size) { + *routes = lease->static_route; + return lease->static_route_size; + } else + return -ENOENT; + + return 0; +} + +sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) { + if (lease) + assert_se(REFCNT_INC(lease->n_ref) >= 2); + + return lease; +} + +sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { + if (lease && REFCNT_DEC(lease->n_ref) <= 0) { + free(lease->hostname); + free(lease->domainname); + free(lease->dns); + free(lease->ntp); + free(lease->static_route); + free(lease->client_id); + free(lease); + } + + return NULL; +} + +static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { + assert(option); + assert(ret); + + if (len == 4) { + *ret = unaligned_read_be32((be32_t*) option); + + if (*ret < min) + *ret = min; + } +} + +static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) { + lease_parse_u32(option, len, (uint32_t *)ret, 0); +} + +static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) { + assert(option); + assert(ret); + + if (len == 2) { + *ret = unaligned_read_be16((be16_t*) option); + + if (*ret < min) + *ret = min; + } +} + +static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) { + assert(option); + assert(ret); + + if (len == 4) + memcpy(ret, option, 4); +} + +static void lease_parse_bool(const uint8_t *option, size_t len, bool *ret) { + assert(option); + assert(ret); + + if (len == 1) + *ret = !!(*option); +} + +static void lease_parse_u8(const uint8_t *option, size_t len, uint8_t *ret, uint8_t min) { + assert(option); + assert(ret); + + if (len == 1) { + *ret = *option; + + if (*ret < min) + *ret = min; + } +} + +static int lease_parse_string(const uint8_t *option, size_t len, char **ret) { + assert(option); + assert(ret); + + if (len >= 1) { + char *string; + + string = strndup((const char *)option, len); + if (!string) + return -errno; + + free(*ret); + *ret = string; + } + + return 0; +} + +static int lease_parse_in_addrs_aux(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size, size_t mult) { + assert(option); + assert(ret); + assert(ret_size); + + if (len && !(len % (4 * mult))) { + size_t size; + struct in_addr *addresses; + + size = len / 4; + + addresses = newdup(struct in_addr, option, size); + if (!addresses) + return -ENOMEM; + + free(*ret); + *ret = addresses; + *ret_size = size; + } + + return 0; +} + +static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) { + return lease_parse_in_addrs_aux(option, len, ret, ret_size, 1); +} + +static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) { + return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2); +} + +static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes, + size_t *routes_size, size_t *routes_allocated) { + + struct in_addr addr; + + assert(option); + assert(routes); + assert(routes_size); + assert(routes_allocated); + + if (!len) + return 0; + + if (len % 8 != 0) + return -EINVAL; + + if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + (len / 8))) + return -ENOMEM; + + while (len >= 8) { + struct sd_dhcp_route *route = *routes + *routes_size; + int r; + + r = in_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen); + if (r < 0) { + log_error("Failed to determine destination prefix length from class based IP, ignoring"); + continue; + } + + lease_parse_be32(option, 4, &addr.s_addr); + route->dst_addr = inet_makeaddr(inet_netof(addr), 0); + option += 4; + + lease_parse_be32(option, 4, &route->gw_addr.s_addr); + option += 4; + + len -= 8; + (*routes_size)++; + } + + return 0; +} + +/* parses RFC3442 Classless Static Route Option */ +static int lease_parse_classless_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes, + size_t *routes_size, size_t *routes_allocated) { + + assert(option); + assert(routes); + assert(routes_size); + assert(routes_allocated); + + /* option format: (subnet-mask-width significant-subnet-octets gateway-ip)* */ + + while (len > 0) { + uint8_t dst_octets; + struct sd_dhcp_route *route; + + if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1)) + return -ENOMEM; + + route = *routes + *routes_size; + + dst_octets = (*option == 0 ? 0 : ((*option - 1) / 8) + 1); + route->dst_prefixlen = *option; + option++; + len--; + + /* can't have more than 4 octets in IPv4 */ + if (dst_octets > 4 || len < dst_octets) + return -EINVAL; + + route->dst_addr.s_addr = 0; + memcpy(&route->dst_addr.s_addr, option, dst_octets); + option += dst_octets; + len -= dst_octets; + + if (len < 4) + return -EINVAL; + + lease_parse_be32(option, 4, &route->gw_addr.s_addr); + option += 4; + len -= 4; + + (*routes_size)++; + } + + return 0; +} + +int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option, + void *user_data) { + sd_dhcp_lease *lease = user_data; + int r; + + assert(lease); + + switch(code) { + + case DHCP_OPTION_TIME_OFFSET: + lease_parse_s32(option, len, &lease->time_offset); + + break; + + case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT: + lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0); + + break; + + case DHCP_OPTION_IP_ADDRESS_LEASE_TIME: + lease_parse_u32(option, len, &lease->lifetime, 1); + + break; + + case DHCP_OPTION_SERVER_IDENTIFIER: + lease_parse_be32(option, len, &lease->server_address); + + break; + + case DHCP_OPTION_SUBNET_MASK: + lease_parse_be32(option, len, &lease->subnet_mask); + + break; + + case DHCP_OPTION_BROADCAST: + lease_parse_be32(option, len, &lease->broadcast); + + break; + + case DHCP_OPTION_ROUTER: + lease_parse_be32(option, len, &lease->router); + + break; + + case DHCP_OPTION_DOMAIN_NAME_SERVER: + r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); + if (r < 0) + return r; + + break; + + case DHCP_OPTION_NTP_SERVER: + r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); + if (r < 0) + return r; + + break; + + case DHCP_OPTION_POLICY_FILTER: + r = lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size); + if (r < 0) + return r; + + break; + + case DHCP_OPTION_STATIC_ROUTE: + r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, + &lease->static_route_allocated); + if (r < 0) + return r; + + break; + + case DHCP_OPTION_INTERFACE_MTU: + lease_parse_u16(option, len, &lease->mtu, 68); + + break; + + case DHCP_OPTION_INTERFACE_MDR: + lease_parse_u16(option, len, &lease->mdr, 576); + + break; + + case DHCP_OPTION_INTERFACE_TTL: + lease_parse_u8(option, len, &lease->ttl, 1); + + break; + + case DHCP_OPTION_BOOT_FILE_SIZE: + lease_parse_u16(option, len, &lease->boot_file_size, 0); + + break; + + case DHCP_OPTION_DOMAIN_NAME: + { + _cleanup_free_ char *domainname = NULL; + + r = lease_parse_string(option, len, &domainname); + if (r < 0) + return r; + + if (!hostname_is_valid(domainname) || is_localhost(domainname)) + break; + + free(lease->domainname); + lease->domainname = domainname; + domainname = NULL; + + break; + } + case DHCP_OPTION_HOST_NAME: + { + _cleanup_free_ char *hostname = NULL; + + r = lease_parse_string(option, len, &hostname); + if (r < 0) + return r; + + if (!hostname_is_valid(hostname) || is_localhost(hostname)) + break; + + free(lease->hostname); + lease->hostname = hostname; + hostname = NULL; + + break; + } + case DHCP_OPTION_ROOT_PATH: + r = lease_parse_string(option, len, &lease->root_path); + if (r < 0) + return r; + + break; + + case DHCP_OPTION_RENEWAL_T1_TIME: + lease_parse_u32(option, len, &lease->t1, 1); + + break; + + case DHCP_OPTION_REBINDING_T2_TIME: + lease_parse_u32(option, len, &lease->t2, 1); + + break; + + case DHCP_OPTION_ENABLE_IP_FORWARDING: + lease_parse_bool(option, len, &lease->ip_forward); + + break; + + case DHCP_OPTION_ENABLE_IP_FORWARDING_NL: + lease_parse_bool(option, len, &lease->ip_forward_non_local); + + break; + + case DHCP_OPTION_CLASSLESS_STATIC_ROUTE: + r = lease_parse_classless_routes(option, len, &lease->static_route, &lease->static_route_size, + &lease->static_route_allocated); + if (r < 0) + return r; + + break; + } + + return 0; +} + +int dhcp_lease_new(sd_dhcp_lease **ret) { + sd_dhcp_lease *lease; + + lease = new0(sd_dhcp_lease, 1); + if (!lease) + return -ENOMEM; + + lease->router = INADDR_ANY; + lease->n_ref = REFCNT_INIT; + + *ret = lease; + return 0; +} + +int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { + _cleanup_free_ char *temp_path = NULL; + _cleanup_fclose_ FILE *f = NULL; + struct in_addr address; + const struct in_addr *addresses; + const uint8_t *client_id; + size_t client_id_len; + const char *string; + uint16_t mtu; + struct sd_dhcp_route *routes; + int r; + + assert(lease); + assert(lease_file); + + r = fopen_temporary(lease_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + r = sd_dhcp_lease_get_address(lease, &address); + if (r < 0) + goto finish; + + fprintf(f, + "# This is private data. Do not parse.\n" + "ADDRESS=%s\n", inet_ntoa(address)); + + r = sd_dhcp_lease_get_netmask(lease, &address); + if (r < 0) + goto finish; + + fprintf(f, "NETMASK=%s\n", inet_ntoa(address)); + + r = sd_dhcp_lease_get_router(lease, &address); + if (r >= 0) + fprintf(f, "ROUTER=%s\n", inet_ntoa(address)); + + r = sd_dhcp_lease_get_server_identifier(lease, &address); + if (r >= 0) + fprintf(f, "SERVER_ADDRESS=%s\n", + inet_ntoa(address)); + + r = sd_dhcp_lease_get_next_server(lease, &address); + if (r >= 0) + fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address)); + + r = sd_dhcp_lease_get_mtu(lease, &mtu); + if (r >= 0) + fprintf(f, "MTU=%" PRIu16 "\n", mtu); + + fputs("DNS=", f); + r = sd_dhcp_lease_get_dns(lease, &addresses); + if (r >= 0) + serialize_in_addrs(f, addresses, r); + fputs("\n", f); + + fputs("NTP=", f); + r = sd_dhcp_lease_get_ntp(lease, &addresses); + if (r >= 0) + serialize_in_addrs(f, addresses, r); + fputs("\n", f); + + r = sd_dhcp_lease_get_domainname(lease, &string); + if (r >= 0) + fprintf(f, "DOMAINNAME=%s\n", string); + + r = sd_dhcp_lease_get_hostname(lease, &string); + if (r >= 0) + fprintf(f, "HOSTNAME=%s\n", string); + + r = sd_dhcp_lease_get_root_path(lease, &string); + if (r >= 0) + fprintf(f, "ROOT_PATH=%s\n", string); + + r = sd_dhcp_lease_get_routes(lease, &routes); + if (r >= 0) + serialize_dhcp_routes(f, "ROUTES", routes, r); + + r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len); + if (r >= 0) { + _cleanup_free_ char *client_id_hex = NULL; + + client_id_hex = hexmem (client_id, client_id_len); + if (!client_id_hex) { + r = -ENOMEM; + goto finish; + } + fprintf(f, "CLIENTID=%s\n", client_id_hex); + } + + r = 0; + + fflush(f); + + if (ferror(f) || rename(temp_path, lease_file) < 0) { + r = -errno; + unlink(lease_file); + unlink(temp_path); + } + +finish: + if (r < 0) + log_error("Failed to save lease data %s: %s", lease_file, strerror(-r)); + + return r; +} + +int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { + _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; + _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL, + *server_address = NULL, *next_server = NULL, + *dns = NULL, *ntp = NULL, *mtu = NULL, + *routes = NULL, *client_id_hex = NULL; + struct in_addr addr; + int r; + + assert(lease_file); + assert(ret); + + r = dhcp_lease_new(&lease); + if (r < 0) + return r; + + r = parse_env_file(lease_file, NEWLINE, + "ADDRESS", &address, + "ROUTER", &router, + "NETMASK", &netmask, + "SERVER_IDENTIFIER", &server_address, + "NEXT_SERVER", &next_server, + "DNS", &dns, + "NTP", &ntp, + "MTU", &mtu, + "DOMAINNAME", &lease->domainname, + "HOSTNAME", &lease->hostname, + "ROOT_PATH", &lease->root_path, + "ROUTES", &routes, + "CLIENTID", &client_id_hex, + NULL); + if (r < 0) { + if (r == -ENOENT) + return 0; + + log_error("Failed to read %s: %s", lease_file, strerror(-r)); + return r; + } + + r = inet_pton(AF_INET, address, &addr); + if (r < 0) + return r; + + lease->address = addr.s_addr; + + if (router) { + r = inet_pton(AF_INET, router, &addr); + if (r < 0) + return r; + + lease->router = addr.s_addr; + } + + r = inet_pton(AF_INET, netmask, &addr); + if (r < 0) + return r; + + lease->subnet_mask = addr.s_addr; + + if (server_address) { + r = inet_pton(AF_INET, server_address, &addr); + if (r < 0) + return r; + + lease->server_address = addr.s_addr; + } + + if (next_server) { + r = inet_pton(AF_INET, next_server, &addr); + if (r < 0) + return r; + + lease->next_server = addr.s_addr; + } + + if (dns) { + r = deserialize_in_addrs(&lease->dns, dns); + if (r < 0) + return r; + + lease->dns_size = r; + } + + if (ntp) { + r = deserialize_in_addrs(&lease->ntp, ntp); + if (r < 0) + return r; + + lease->ntp_size = r; + } + + if (mtu) { + uint16_t u; + if (sscanf(mtu, "%" SCNu16, &u) > 0) + lease->mtu = u; + } + + if (routes) { + r = deserialize_dhcp_routes(&lease->static_route, &lease->static_route_size, + &lease->static_route_allocated, routes); + if (r < 0) + return r; + } + + if (client_id_hex) { + if (strlen (client_id_hex) % 2) + return -EINVAL; + + lease->client_id = unhexmem (client_id_hex, strlen (client_id_hex)); + if (!lease->client_id) + return -ENOMEM; + lease->client_id_len = strlen (client_id_hex) / 2; + } + + *ret = lease; + lease = NULL; + + return 0; +} + +int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) { + struct in_addr address; + struct in_addr mask; + int r; + + assert(lease); + + address.s_addr = lease->address; + + /* fall back to the default subnet masks based on address class */ + r = in_addr_default_subnet_mask(&address, &mask); + if (r < 0) + return r; + + lease->subnet_mask = mask.s_addr; + + return 0; +} + +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, + size_t *client_id_len) { + assert_return(lease, -EINVAL); + assert_return(client_id, -EINVAL); + assert_return(client_id_len, -EINVAL); + + *client_id = lease->client_id; + *client_id_len = lease->client_id_len; + return 0; +} + +int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id, + size_t client_id_len) { + assert_return(lease, -EINVAL); + assert_return((!client_id && !client_id_len) || + (client_id && client_id_len), -EINVAL); + + free (lease->client_id); + lease->client_id = NULL; + lease->client_id_len = 0; + + if (client_id) { + lease->client_id = memdup (client_id, client_id_len); + lease->client_id_len = client_id_len; + } + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c new file mode 100644 index 00000000..6c5a6ab5 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c @@ -0,0 +1,1242 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include + +#if 0 /* NM_IGNORED */ +#include "udev.h" +#include "udev-util.h" +#include "virt.h" +#endif +#include "siphash24.h" +#include "util.h" +#include "refcnt.h" + +#include "network-internal.h" +#include "sd-dhcp6-client.h" +#include "dhcp6-protocol.h" +#include "dhcp6-internal.h" +#include "dhcp6-lease-internal.h" + +#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) + +/* RFC 3315 section 9.1: + * A DUID can be no more than 128 octets long (not including the type code). + */ +#define MAX_DUID_LEN 128 + +#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN + +struct sd_dhcp6_client { + RefCount n_ref; + + enum DHCP6State state; + sd_event *event; + int event_priority; + int index; + uint8_t mac_addr[MAX_MAC_ADDR_LEN]; + size_t mac_addr_len; + uint16_t arp_type; + char ifname[IFNAMSIZ]; + DHCP6IA ia_na; + be32_t transaction_id; + usec_t transaction_start; + struct sd_dhcp6_lease *lease; + int fd; + be16_t *req_opts; + size_t req_opts_allocated; + size_t req_opts_len; + sd_event_source *receive_message; + usec_t retransmit_time; + uint8_t retransmit_count; + sd_event_source *timeout_resend; + sd_event_source *timeout_resend_expire; + sd_dhcp6_client_cb_t cb; + void *userdata; + union { + struct { + uint16_t type; /* DHCP6_DUID_LLT */ + uint16_t htype; + uint32_t time; + uint8_t haddr[0]; + } _packed_ llt; + struct { + uint16_t type; /* DHCP6_DUID_EN */ + uint32_t pen; + uint8_t id[8]; + } _packed_ en; + struct { + uint16_t type; /* DHCP6_DUID_LL */ + uint16_t htype; + uint8_t haddr[0]; + } _packed_ ll; + struct { + uint16_t type; /* DHCP6_DUID_UUID */ + sd_id128_t uuid; + } _packed_ uuid; + struct { + uint16_t type; + uint8_t data[MAX_DUID_LEN]; + } _packed_ raw; + } duid; + size_t duid_len; +}; + +static const uint16_t default_req_opts[] = { + DHCP6_OPTION_DNS_SERVERS, + DHCP6_OPTION_DOMAIN_LIST, + DHCP6_OPTION_NTP_SERVER, +}; + +const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = { + [DHCP6_SOLICIT] = "SOLICIT", + [DHCP6_ADVERTISE] = "ADVERTISE", + [DHCP6_REQUEST] = "REQUEST", + [DHCP6_CONFIRM] = "CONFIRM", + [DHCP6_RENEW] = "RENEW", + [DHCP6_REBIND] = "REBIND", + [DHCP6_REPLY] = "REPLY", + [DHCP6_RELEASE] = "RELEASE", + [DHCP6_DECLINE] = "DECLINE", + [DHCP6_RECONFIGURE] = "RECONFIGURE", + [DHCP6_INFORMATION_REQUEST] = "INFORMATION-REQUEST", + [DHCP6_RELAY_FORW] = "RELAY-FORW", + [DHCP6_RELAY_REPL] = "RELAY-REPL", +}; + +DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_type, int); + +const char * dhcp6_message_status_table[_DHCP6_STATUS_MAX] = { + [DHCP6_STATUS_SUCCESS] = "Success", + [DHCP6_STATUS_UNSPEC_FAIL] = "Unspecified failure", + [DHCP6_STATUS_NO_ADDRS_AVAIL] = "No addresses available", + [DHCP6_STATUS_NO_BINDING] = "Binding unavailable", + [DHCP6_STATUS_NOT_ON_LINK] = "Not on link", + [DHCP6_STATUS_USE_MULTICAST] = "Use multicast", +}; + +DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int); + +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref); +#define _cleanup_dhcp6_client_unref_ _cleanup_(sd_dhcp6_client_unrefp) + +#define DHCP6_CLIENT_DONT_DESTROY(client) \ + _cleanup_dhcp6_client_unref_ _unused_ sd_dhcp6_client *_dont_destroy_##client = sd_dhcp6_client_ref(client) + +static int client_start(sd_dhcp6_client *client, enum DHCP6State state); + +int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, + sd_dhcp6_client_cb_t cb, void *userdata) +{ + assert_return(client, -EINVAL); + + client->cb = 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); + + client->index = interface_index; + + return 0; +} + +int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr, + size_t addr_len, uint16_t arp_type) +{ + assert_return(client, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL); + assert_return(arp_type > 0, -EINVAL); + + if (arp_type == ARPHRD_ETHER) + assert_return(addr_len == ETH_ALEN, -EINVAL); + else if (arp_type == ARPHRD_INFINIBAND) + assert_return(addr_len == INFINIBAND_ALEN, -EINVAL); + else + return -EINVAL; + + if (client->mac_addr_len == addr_len && + memcmp(&client->mac_addr, addr, addr_len) == 0) + return 0; + + memcpy(&client->mac_addr, addr, addr_len); + client->mac_addr_len = addr_len; + client->arp_type = arp_type; + + return 0; +} + +int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid, + size_t duid_len) +{ + assert_return(client, -EINVAL); + assert_return(duid, -EINVAL); + assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL); + + switch (type) { + case DHCP6_DUID_LLT: + if (duid_len <= sizeof(client->duid.llt) - 2) + return -EINVAL; + break; + case DHCP6_DUID_EN: + if (duid_len != sizeof(client->duid.en) - 2) + return -EINVAL; + break; + case DHCP6_DUID_LL: + if (duid_len <= sizeof(client->duid.ll) - 2) + return -EINVAL; + break; + case DHCP6_DUID_UUID: + if (duid_len != sizeof(client->duid.uuid) - 2) + return -EINVAL; + break; + default: + /* accept unknown type in order to be forward compatible */ + break; + } + + client->duid.raw.type = htobe16(type); + memcpy(&client->duid.raw.data, duid, duid_len); + client->duid_len = duid_len + 2; /* +2 for sizeof(type) */ + + return 0; +} + +int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, + uint16_t option) { + size_t t; + + assert_return(client, -EINVAL); + assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY); + + switch(option) { + case DHCP6_OPTION_DNS_SERVERS: + case DHCP6_OPTION_DOMAIN_LIST: + case DHCP6_OPTION_SNTP_SERVERS: + case DHCP6_OPTION_NTP_SERVER: + break; + + default: + return -EINVAL; + } + + for (t = 0; t < client->req_opts_len; t++) + if (client->req_opts[t] == htobe16(option)) + return -EEXIST; + + if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated, + client->req_opts_len + 1)) + return -ENOMEM; + + client->req_opts[client->req_opts_len++] = htobe16(option); + + return 0; +} + +int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) { + assert_return(client, -EINVAL); + assert_return(ret, -EINVAL); + + if (!client->lease) + return -ENOMSG; + + *ret = sd_dhcp6_lease_ref(client->lease); + + return 0; +} + +static void client_notify(sd_dhcp6_client *client, int event) { + if (client->cb) + client->cb(client, event, client->userdata); +} + +static int client_reset(sd_dhcp6_client *client) { + assert_return(client, -EINVAL); + + client->receive_message = + sd_event_source_unref(client->receive_message); + + client->fd = safe_close(client->fd); + + client->transaction_id = 0; + client->transaction_start = 0; + + client->ia_na.timeout_t1 = + sd_event_source_unref(client->ia_na.timeout_t1); + client->ia_na.timeout_t2 = + sd_event_source_unref(client->ia_na.timeout_t2); + + client->retransmit_time = 0; + client->retransmit_count = 0; + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + client->timeout_resend_expire = + sd_event_source_unref(client->timeout_resend_expire); + + client->state = DHCP6_STATE_STOPPED; + + return 0; +} + +static void client_stop(sd_dhcp6_client *client, int error) { + DHCP6_CLIENT_DONT_DESTROY(client); + + assert(client); + + client_notify(client, error); + + client_reset(client); +} + +static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { + _cleanup_free_ DHCP6Message *message = NULL; + struct in6_addr all_servers = + IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT; + size_t len, optlen = 512; + uint8_t *opt; + int r; + usec_t elapsed_usec; + be16_t elapsed_time; + + len = sizeof(DHCP6Message) + optlen; + + message = malloc0(len); + if (!message) + return -ENOMEM; + + opt = (uint8_t *)(message + 1); + + message->transaction_id = client->transaction_id; + + switch(client->state) { + case DHCP6_STATE_SOLICITATION: + message->type = DHCP6_SOLICIT; + + r = dhcp6_option_append(&opt, &optlen, + DHCP6_OPTION_RAPID_COMMIT, 0, NULL); + if (r < 0) + return r; + + r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na); + if (r < 0) + return r; + + break; + + case DHCP6_STATE_REQUEST: + case DHCP6_STATE_RENEW: + + if (client->state == DHCP6_STATE_REQUEST) + message->type = DHCP6_REQUEST; + else + message->type = DHCP6_RENEW; + + r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_SERVERID, + client->lease->serverid_len, + client->lease->serverid); + if (r < 0) + return r; + + r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia); + if (r < 0) + return r; + + break; + + case DHCP6_STATE_REBIND: + message->type = DHCP6_REBIND; + + r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia); + if (r < 0) + return r; + + break; + + case DHCP6_STATE_STOPPED: + case DHCP6_STATE_BOUND: + return -EINVAL; + } + + r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO, + client->req_opts_len * sizeof(be16_t), + client->req_opts); + if (r < 0) + return r; + + r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID, + client->duid_len, &client->duid); + if (r < 0) + return r; + + elapsed_usec = time_now - client->transaction_start; + if (elapsed_usec < 0xffff * USEC_PER_MSEC * 10) + elapsed_time = htobe16(elapsed_usec / USEC_PER_MSEC / 10); + else + elapsed_time = 0xffff; + + r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ELAPSED_TIME, + sizeof(elapsed_time), &elapsed_time); + if (r < 0) + return r; + + r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message, + len - optlen); + if (r < 0) + return r; + + log_dhcp6_client(client, "Sent %s", + dhcp6_message_type_to_string(message->type)); + + return 0; +} + +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); + + client->lease->ia.timeout_t2 = + sd_event_source_unref(client->lease->ia.timeout_t2); + + log_dhcp6_client(client, "Timeout T2"); + + client_start(client, DHCP6_STATE_REBIND); + + return 0; +} + +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); + + client->lease->ia.timeout_t1 = + sd_event_source_unref(client->lease->ia.timeout_t1); + + log_dhcp6_client(client, "Timeout T1"); + + client_start(client, DHCP6_STATE_RENEW); + + return 0; +} + +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; + + assert(s); + assert(client); + assert(client->event); + + state = client->state; + + client_stop(client, DHCP6_EVENT_RESEND_EXPIRE); + + /* RFC 3315, section 18.1.4., says that "...the client may choose to + use a Solicit message to locate a new DHCP server..." */ + if (state == DHCP6_STATE_REBIND) + client_start(client, DHCP6_STATE_SOLICITATION); + + return 0; +} + +static usec_t client_timeout_compute_random(usec_t val) { + return val - val / 10 + + (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) { + int r = 0; + sd_dhcp6_client *client = userdata; + usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0; + usec_t max_retransmit_duration = 0; + uint8_t max_retransmit_count = 0; + char time_string[FORMAT_TIMESPAN_MAX]; + uint32_t expire = 0; + + assert(s); + assert(client); + assert(client->event); + + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + + switch (client->state) { + case DHCP6_STATE_SOLICITATION: + + if (client->retransmit_count && client->lease) { + client_start(client, DHCP6_STATE_REQUEST); + return 0; + } + + init_retransmit_time = DHCP6_SOL_TIMEOUT; + max_retransmit_time = DHCP6_SOL_MAX_RT; + + break; + + case DHCP6_STATE_REQUEST: + init_retransmit_time = DHCP6_REQ_TIMEOUT; + max_retransmit_time = DHCP6_REQ_MAX_RT; + max_retransmit_count = DHCP6_REQ_MAX_RC; + + break; + + case DHCP6_STATE_RENEW: + init_retransmit_time = DHCP6_REN_TIMEOUT; + max_retransmit_time = DHCP6_REN_MAX_RT; + + /* RFC 3315, section 18.1.3. says max retransmit duration will + be the remaining time until T2. Instead of setting MRD, + wait for T2 to trigger with the same end result */ + + break; + + case DHCP6_STATE_REBIND: + init_retransmit_time = DHCP6_REB_TIMEOUT; + max_retransmit_time = DHCP6_REB_MAX_RT; + + if (!client->timeout_resend_expire) { + r = dhcp6_lease_ia_rebind_expire(&client->lease->ia, + &expire); + if (r < 0) { + client_stop(client, r); + return 0; + } + max_retransmit_duration = expire * USEC_PER_SEC; + } + + break; + + case DHCP6_STATE_STOPPED: + case DHCP6_STATE_BOUND: + return 0; + } + + if (max_retransmit_count && + client->retransmit_count >= max_retransmit_count) { + client_stop(client, DHCP6_EVENT_RETRANS_MAX); + return 0; + } + + r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now); + if (r < 0) + goto error; + + r = client_send_message(client, time_now); + if (r >= 0) + client->retransmit_count++; + + if (!client->retransmit_time) { + client->retransmit_time = + client_timeout_compute_random(init_retransmit_time); + + if (client->state == DHCP6_STATE_SOLICITATION) + client->retransmit_time += init_retransmit_time / 10; + + } else { + if (max_retransmit_time && + client->retransmit_time > max_retransmit_time / 2) + client->retransmit_time = client_timeout_compute_random(max_retransmit_time); + else + client->retransmit_time += client_timeout_compute_random(client->retransmit_time); + } + + log_dhcp6_client(client, "Next retransmission in %s", + format_timespan(time_string, FORMAT_TIMESPAN_MAX, + client->retransmit_time, 0)); + + r = sd_event_add_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + time_now + client->retransmit_time, + 10 * USEC_PER_MSEC, client_timeout_resend, + client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer"); + if (r < 0) + goto error; + + if (max_retransmit_duration && !client->timeout_resend_expire) { + + log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs", + max_retransmit_duration / USEC_PER_SEC); + + r = sd_event_add_time(client->event, + &client->timeout_resend_expire, + clock_boottime_or_monotonic(), + time_now + max_retransmit_duration, + USEC_PER_SEC, + client_timeout_resend_expire, client); + if (r < 0) + goto error; + + r = sd_event_source_set_priority(client->timeout_resend_expire, + client->event_priority); + if (r < 0) + goto error; + + r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer"); + if (r < 0) + goto error; + } + +error: + if (r < 0) + client_stop(client, r); + + return 0; +} + +static int client_ensure_iaid(sd_dhcp6_client *client) { + const char *name; + uint64_t id; + + assert(client); + + if (client->ia_na.id) + return 0; + + name = client->ifname; + if (name) + siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes); + else + /* fall back to mac address if no predictable name available */ + siphash24((uint8_t*)&id, &client->mac_addr, + client->mac_addr_len, HASH_KEY.bytes); + + /* fold into 32 bits */ + client->ia_na.id = (id & 0xffffffff) ^ (id >> 32); + + return 0; +} + +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; + size_t optlen, id_len; + bool clientid = false; + be32_t iaid_lease; + + option = (uint8_t *)message + sizeof(DHCP6Message); + len -= sizeof(DHCP6Message); + + while ((r = dhcp6_option_parse(&option, &len, &optcode, &optlen, + &optval)) >= 0) { + switch (optcode) { + case DHCP6_OPTION_CLIENTID: + if (clientid) { + log_dhcp6_client(client, "%s contains multiple clientids", + dhcp6_message_type_to_string(message->type)); + return -EINVAL; + } + + if (optlen != client->duid_len || + memcmp(&client->duid, optval, optlen) != 0) { + log_dhcp6_client(client, "%s DUID does not match", + dhcp6_message_type_to_string(message->type)); + + return -EINVAL; + } + clientid = true; + + break; + + case DHCP6_OPTION_SERVERID: + r = dhcp6_lease_get_serverid(lease, &id, &id_len); + if (r >= 0 && id) { + log_dhcp6_client(client, "%s contains multiple serverids", + dhcp6_message_type_to_string(message->type)); + return -EINVAL; + } + + r = dhcp6_lease_set_serverid(lease, optval, optlen); + if (r < 0) + return r; + + break; + + case DHCP6_OPTION_PREFERENCE: + if (optlen != 1) + return -EINVAL; + + r = dhcp6_lease_set_preference(lease, *optval); + if (r < 0) + return r; + + break; + + case DHCP6_OPTION_STATUS_CODE: + if (optlen < 2) + return -EINVAL; + + status = optval[0] << 8 | optval[1]; + if (status) { + log_dhcp6_client(client, "%s Status %s", + dhcp6_message_type_to_string(message->type), + dhcp6_message_status_to_string(status)); + return -EINVAL; + } + + break; + + case DHCP6_OPTION_IA_NA: + r = dhcp6_option_parse_ia(&optval, &optlen, optcode, + &lease->ia); + if (r < 0 && r != -ENOMSG) + return r; + + r = dhcp6_lease_get_iaid(lease, &iaid_lease); + if (r < 0) + return r; + + if (client->ia_na.id != iaid_lease) { + log_dhcp6_client(client, "%s has wrong IAID", + dhcp6_message_type_to_string(message->type)); + return -EINVAL; + } + + break; + + case DHCP6_OPTION_RAPID_COMMIT: + r = dhcp6_lease_set_rapid_commit(lease); + if (r < 0) + return r; + + break; + } + } + + if ((r < 0 && r != -ENOMSG) || !clientid) { + log_dhcp6_client(client, "%s has incomplete options", + dhcp6_message_type_to_string(message->type)); + return -EINVAL; + } + + r = dhcp6_lease_get_serverid(lease, &id, &id_len); + if (r < 0) + log_dhcp6_client(client, "%s has no server id", + dhcp6_message_type_to_string(message->type)); + + return r; +} + +static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, + size_t len) +{ + int r; + _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; + bool rapid_commit; + + if (reply->type != DHCP6_REPLY) + return 0; + + r = dhcp6_lease_new(&lease); + if (r < 0) + return -ENOMEM; + + r = client_parse_message(client, reply, len, lease); + if (r < 0) + return r; + + if (client->state == DHCP6_STATE_SOLICITATION) { + r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit); + if (r < 0) + return r; + + if (!rapid_commit) + return 0; + } + + if (client->lease) + dhcp6_lease_clear_timers(&client->lease->ia); + + client->lease = sd_dhcp6_lease_unref(client->lease); + client->lease = lease; + lease = NULL; + + return DHCP6_STATE_BOUND; +} + +static int client_receive_advertise(sd_dhcp6_client *client, + DHCP6Message *advertise, size_t len) { + int r; + _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL; + uint8_t pref_advertise = 0, pref_lease = 0; + + if (advertise->type != DHCP6_ADVERTISE) + return 0; + + r = dhcp6_lease_new(&lease); + if (r < 0) + return r; + + r = client_parse_message(client, advertise, len, lease); + if (r < 0) + return r; + + r = dhcp6_lease_get_preference(lease, &pref_advertise); + if (r < 0) + return r; + + r = dhcp6_lease_get_preference(client->lease, &pref_lease); + if (!client->lease || r < 0 || pref_advertise > pref_lease) { + sd_dhcp6_lease_unref(client->lease); + client->lease = lease; + lease = NULL; + r = 0; + } + + if (pref_advertise == 255 || client->retransmit_count > 1) + r = DHCP6_STATE_REQUEST; + + return r; +} + +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; + int r, buflen, len; + + assert(s); + assert(client); + assert(client->event); + + r = ioctl(fd, FIONREAD, &buflen); + if (r < 0 || buflen <= 0) + buflen = DHCP6_MIN_OPTIONS_SIZE; + + message = malloc0(buflen); + if (!message) + return -ENOMEM; + + len = read(fd, message, buflen); + if ((size_t)len < sizeof(DHCP6Message)) { + log_dhcp6_client(client, "could not receive message from UDP socket: %m"); + return 0; + } + + switch(message->type) { + case DHCP6_SOLICIT: + case DHCP6_REQUEST: + case DHCP6_CONFIRM: + case DHCP6_RENEW: + case DHCP6_REBIND: + case DHCP6_RELEASE: + case DHCP6_DECLINE: + case DHCP6_INFORMATION_REQUEST: + case DHCP6_RELAY_FORW: + case DHCP6_RELAY_REPL: + return 0; + + case DHCP6_ADVERTISE: + case DHCP6_REPLY: + case DHCP6_RECONFIGURE: + break; + + default: + log_dhcp6_client(client, "unknown message type %d", + message->type); + return 0; + } + + if (client->transaction_id != (message->transaction_id & + htobe32(0x00ffffff))) + return 0; + + switch (client->state) { + case DHCP6_STATE_SOLICITATION: + r = client_receive_advertise(client, message, len); + + if (r == DHCP6_STATE_REQUEST) { + client_start(client, r); + + break; + } + + /* fall through for Soliciation Rapid Commit option check */ + case DHCP6_STATE_REQUEST: + case DHCP6_STATE_RENEW: + case DHCP6_STATE_REBIND: + + r = client_receive_reply(client, message, len); + if (r < 0) + return 0; + + if (r == DHCP6_STATE_BOUND) { + + r = client_start(client, DHCP6_STATE_BOUND); + if (r < 0) { + client_stop(client, r); + return 0; + } + + client_notify(client, DHCP6_EVENT_IP_ACQUIRE); + } + + break; + + case DHCP6_STATE_BOUND: + + break; + + case DHCP6_STATE_STOPPED: + return 0; + } + + if (r >= 0) { + log_dhcp6_client(client, "Recv %s", + dhcp6_message_type_to_string(message->type)); + } + + return 0; +} + +static int client_start(sd_dhcp6_client *client, enum DHCP6State state) +{ + int r; + usec_t timeout, time_now; + char time_string[FORMAT_TIMESPAN_MAX]; + + assert_return(client, -EINVAL); + assert_return(client->event, -EINVAL); + assert_return(client->index > 0, -EINVAL); + assert_return(client->state != state, -EINVAL); + + client->timeout_resend_expire = + sd_event_source_unref(client->timeout_resend_expire); + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + client->retransmit_time = 0; + client->retransmit_count = 0; + + if (client->state == DHCP6_STATE_STOPPED) { + time_now = now(clock_boottime_or_monotonic()); + } else { + r = sd_event_now(client->event, clock_boottime_or_monotonic(), + &time_now); + if (r < 0) + return r; + } + + switch (state) { + case DHCP6_STATE_STOPPED: + case DHCP6_STATE_SOLICITATION: + + r = client_ensure_iaid(client); + if (r < 0) + return r; + + r = dhcp6_network_bind_udp_socket(client->index, NULL); + if (r < 0) + return r; + + client->fd = r; + + r = sd_event_add_io(client->event, &client->receive_message, + client->fd, EPOLLIN, client_receive_message, + client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->receive_message, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->receive_message, "dhcp6-receive-message"); + if (r < 0) + return r; + + client->state = DHCP6_STATE_SOLICITATION; + + break; + + case DHCP6_STATE_REQUEST: + case DHCP6_STATE_RENEW: + case DHCP6_STATE_REBIND: + + client->state = state; + + break; + + case DHCP6_STATE_BOUND: + + 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", + be32toh(client->lease->ia.lifetime_t1), + be32toh(client->lease->ia.lifetime_t2)); + + return 0; + } + + timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t1) * USEC_PER_SEC); + + log_dhcp6_client(client, "T1 expires in %s", + format_timespan(time_string, + FORMAT_TIMESPAN_MAX, + timeout, 0)); + + r = sd_event_add_time(client->event, + &client->lease->ia.timeout_t1, + clock_boottime_or_monotonic(), time_now + timeout, + 10 * USEC_PER_SEC, client_timeout_t1, + client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->lease->ia.timeout_t1, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout"); + if (r < 0) + return r; + + timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC); + + log_dhcp6_client(client, "T2 expires in %s", + format_timespan(time_string, + FORMAT_TIMESPAN_MAX, + timeout, 0)); + + r = sd_event_add_time(client->event, + &client->lease->ia.timeout_t2, + clock_boottime_or_monotonic(), time_now + timeout, + 10 * USEC_PER_SEC, client_timeout_t2, + client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->lease->ia.timeout_t2, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout"); + if (r < 0) + return r; + + client->state = state; + + return 0; + } + + client->transaction_id = random_u32() & htobe32(0x00ffffff); + client->transaction_start = time_now; + + r = sd_event_add_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), 0, 0, client_timeout_resend, + client); + if (r < 0) + return r; + + r = sd_event_source_set_priority(client->timeout_resend, + client->event_priority); + if (r < 0) + return r; + + r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout"); + if (r < 0) + return r; + + return 0; +} + +int sd_dhcp6_client_stop(sd_dhcp6_client *client) +{ + client_stop(client, DHCP6_EVENT_STOP); + + return 0; +} + +int sd_dhcp6_client_start(sd_dhcp6_client *client) +{ + int r = 0; + + assert_return(client, -EINVAL); + assert_return(client->event, -EINVAL); + assert_return(client->index > 0, -EINVAL); + + r = client_reset(client); + if (r < 0) + return r; + + return client_start(client, DHCP6_STATE_SOLICITATION); +} + +int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, + int priority) +{ + int r; + + assert_return(client, -EINVAL); + assert_return(!client->event, -EBUSY); + + if (event) + client->event = sd_event_ref(event); + else { + r = sd_event_default(&client->event); + if (r < 0) + return 0; + } + + client->event_priority = priority; + + return 0; +} + +int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) { + assert_return(client, -EINVAL); + + client->event = sd_event_unref(client->event); + + return 0; +} + +sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { + if (!client) + return NULL; + + return client->event; +} + +sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) { + if (client) + assert_se(REFCNT_INC(client->n_ref) >= 2); + + return client; +} + +sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { + if (client && REFCNT_DEC(client->n_ref) <= 0) { + client_reset(client); + + sd_dhcp6_client_detach_event(client); + + free(client->req_opts); + free(client); + + return NULL; + } + + return client; +} + +int sd_dhcp6_client_new(sd_dhcp6_client **ret) +{ + _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL; +#if 0 /* NM_IGNORED */ + sd_id128_t machine_id; + int r; +#endif + size_t t; + + assert_return(ret, -EINVAL); + + client = new0(sd_dhcp6_client, 1); + if (!client) + return -ENOMEM; + + client->n_ref = REFCNT_INIT; + + client->ia_na.type = DHCP6_OPTION_IA_NA; + + client->index = -1; + + client->fd = -1; + +#if 0 /* NM_IGNORED */ + /* initialize DUID */ + client->duid.en.type = htobe16(DHCP6_DUID_EN); + client->duid.en.pen = htobe32(SYSTEMD_PEN); + client->duid_len = sizeof(client->duid.en); + + r = sd_id128_get_machine(&machine_id); + if (r < 0) + return r; + + /* a bit of snake-oil perhaps, but no need to expose the machine-id + directly */ + siphash24(client->duid.en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes); +#endif + + client->req_opts_len = ELEMENTSOF(default_req_opts); + + client->req_opts = new0(be16_t, client->req_opts_len); + if (!client->req_opts) + return -ENOMEM; + + for (t = 0; t < client->req_opts_len; t++) + client->req_opts[t] = htobe16(default_req_opts[t]); + + *ret = client; + client = NULL; + + return 0; +} + +/*******************************************/ +/* NetworkManager additions */ + +int sd_dhcp6_client_set_ifname(sd_dhcp6_client *client, const char *ifname) +{ + assert_return(client, -EINVAL); + assert_return(ifname, -EINVAL); + assert_return(strlen (ifname) < sizeof (client->ifname), -EINVAL); + + strcpy(client->ifname, ifname); + return 0; +} + diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c new file mode 100644 index 00000000..0df6984d --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c @@ -0,0 +1,223 @@ +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include + +#include "util.h" + +#include "dhcp6-lease-internal.h" + +int dhcp6_lease_clear_timers(DHCP6IA *ia) { + assert_return(ia, -EINVAL); + + ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1); + ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2); + + return 0; +} + +int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) { + DHCP6Address *addr; + uint32_t valid = 0, t; + + assert_return(ia, -EINVAL); + assert_return(expire, -EINVAL); + + LIST_FOREACH(addresses, addr, ia->addresses) { + t = be32toh(addr->iaaddr.lifetime_valid); + if (valid < t) + valid = t; + } + + t = be32toh(ia->lifetime_t2); + if (t > valid) + return -EINVAL; + + *expire = valid - t; + + return 0; +} + +DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) { + DHCP6Address *address; + + if (!ia) + return NULL; + + dhcp6_lease_clear_timers(ia); + + while (ia->addresses) { + address = ia->addresses; + + LIST_REMOVE(addresses, ia->addresses, address); + + free(address); + } + + return NULL; +} + +int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, + size_t len) { + assert_return(lease, -EINVAL); + assert_return(id, -EINVAL); + + free(lease->serverid); + + lease->serverid = memdup(id, len); + if (!lease->serverid) + return -EINVAL; + + lease->serverid_len = len; + + return 0; +} + +int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) { + assert_return(lease, -EINVAL); + assert_return(id, -EINVAL); + assert_return(len, -EINVAL); + + *id = lease->serverid; + *len = lease->serverid_len; + + return 0; +} + +int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) { + assert_return(lease, -EINVAL); + + lease->preference = preference; + + return 0; +} + +int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) { + assert_return(lease, -EINVAL); + assert_return(preference, -EINVAL); + + *preference = lease->preference; + + return 0; +} + +int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) { + assert_return(lease, -EINVAL); + + lease->rapid_commit = true; + + return 0; +} + +int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) { + assert_return(lease, -EINVAL); + assert_return(rapid_commit, -EINVAL); + + *rapid_commit = lease->rapid_commit; + + return 0; +} + +int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) { + assert_return(lease, -EINVAL); + assert_return(iaid, -EINVAL); + + *iaid = lease->ia.id; + + return 0; +} + +int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease, + struct in6_addr *addr, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(lifetime_preferred, -EINVAL); + assert_return(lifetime_valid, -EINVAL); + + if (!lease->addr_iter) + return -ENOMSG; + + memcpy(addr, &lease->addr_iter->iaaddr.address, + sizeof(struct in6_addr)); + *lifetime_preferred = + be32toh(lease->addr_iter->iaaddr.lifetime_preferred); + *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid); + + lease->addr_iter = lease->addr_iter->addresses_next; + + return 0; +} + +int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease, + struct in6_addr *addr, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + assert_return(lifetime_preferred, -EINVAL); + assert_return(lifetime_valid, -EINVAL); + + if (!lease->ia.addresses) + return -ENOMSG; + + lease->addr_iter = lease->ia.addresses; + + return sd_dhcp6_lease_get_next_address(lease, addr, lifetime_preferred, + lifetime_valid); +} + +sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) { + if (lease) + assert_se(REFCNT_INC(lease->n_ref) >= 2); + + return lease; +} + +sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { + if (lease && REFCNT_DEC(lease->n_ref) <= 0) { + free(lease->serverid); + dhcp6_lease_free_ia(&lease->ia); + + free(lease); + } + + return NULL; +} + +int dhcp6_lease_new(sd_dhcp6_lease **ret) { + sd_dhcp6_lease *lease; + + lease = new0(sd_dhcp6_lease, 1); + if (!lease) + return -ENOMEM; + + lease->n_ref = REFCNT_INIT; + + LIST_HEAD_INIT(lease->ia.addresses); + + *ret = lease; + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/async.h b/src/dhcp-manager/systemd-dhcp/src/shared/async.h new file mode 100644 index 00000000..7f1ef795 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/async.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 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 . +***/ + +int asynchronous_job(void* (*func)(void *p), void *arg); + +int asynchronous_sync(void); +int asynchronous_close(int fd); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c new file mode 100644 index 00000000..0757d5d9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c @@ -0,0 +1,817 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "config.h" + +#include + +#include "util.h" +#include "strv.h" +#include "utf8.h" +#include "ctype.h" +#include "fileio.h" + +int write_string_stream(FILE *f, const char *line) { + assert(f); + assert(line); + + errno = 0; + + fputs(line, f); + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +int write_string_file(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(line); + + f = fopen(fn, "we"); + if (!f) + return -errno; + + return write_string_stream(f, line); +} + +int write_string_file_no_create(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + int fd; + + assert(fn); + assert(line); + + /* We manually build our own version of fopen(..., "we") that + * works without O_CREAT */ + fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + f = fdopen(fd, "we"); + if (!f) { + safe_close(fd); + return -errno; + } + + return write_string_stream(f, line); +} + +int write_string_file_atomic(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + int r; + + assert(fn); + assert(line); + + r = fopen_temporary(fn, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + r = write_string_stream(f, line); + if (r >= 0) { + if (rename(p, fn) < 0) + r = -errno; + } + + if (r < 0) + unlink(p); + + return r; +} + +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + t[0] = 0; + } + + c = strdup(t); + if (!c) + return -ENOMEM; + truncate_nl(c); + + *line = c; + return 0; +} + +int read_full_stream(FILE *f, char **contents, size_t *size) { + size_t n, l; + _cleanup_free_ char *buf = NULL; + struct stat st; + + assert(f); + assert(contents); + + if (fstat(fileno(f), &st) < 0) + return -errno; + + n = LINE_MAX; + + if (S_ISREG(st.st_mode)) { + + /* Safety check */ + if (st.st_size > 4*1024*1024) + return -E2BIG; + + /* Start with the right file size, but be prepared for + * files from /proc which generally report a file size + * of 0 */ + if (st.st_size > 0) + n = st.st_size; + } + + l = 0; + for (;;) { + char *t; + size_t k; + + t = realloc(buf, n+1); + if (!t) + return -ENOMEM; + + buf = t; + k = fread(buf + l, 1, n - l, f); + + if (k <= 0) { + if (ferror(f)) + return -errno; + + break; + } + + l += k; + n *= 2; + + /* Safety check */ + if (n > 4*1024*1024) + return -E2BIG; + } + + buf[l] = 0; + *contents = buf; + buf = NULL; /* do not free */ + + if (size) + *size = l; + + return 0; +} + +int read_full_file(const char *fn, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(contents); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + return read_full_stream(f, contents, size); +} + +static int parse_env_file_internal( + FILE *f, + const char *fname, + const char *newline, + int (*push) (const char *filename, unsigned line, + const char *key, char *value, void *userdata, int *n_pushed), + void *userdata, + int *n_pushed) { + + _cleanup_free_ char *contents = NULL, *key = NULL; + size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; + char *p, *value = NULL; + int r; + unsigned line = 1; + + enum { + PRE_KEY, + KEY, + PRE_VALUE, + VALUE, + VALUE_ESCAPE, + SINGLE_QUOTE_VALUE, + SINGLE_QUOTE_VALUE_ESCAPE, + DOUBLE_QUOTE_VALUE, + DOUBLE_QUOTE_VALUE_ESCAPE, + COMMENT, + COMMENT_ESCAPE + } state = PRE_KEY; + + assert(newline); + + if (f) + r = read_full_stream(f, &contents, NULL); + else + r = read_full_file(fname, &contents, NULL); + if (r < 0) + return r; + + for (p = contents; *p; p++) { + char c = *p; + + switch (state) { + + case PRE_KEY: + if (strchr(COMMENTS, c)) + state = COMMENT; + else if (!strchr(WHITESPACE, c)) { + state = KEY; + last_key_whitespace = (size_t) -1; + + if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) { + r = -ENOMEM; + goto fail; + } + + key[n_key++] = c; + } + break; + + case KEY: + if (strchr(newline, c)) { + state = PRE_KEY; + line ++; + n_key = 0; + } else if (c == '=') { + state = PRE_VALUE; + last_value_whitespace = (size_t) -1; + } else { + if (!strchr(WHITESPACE, c)) + last_key_whitespace = (size_t) -1; + else if (last_key_whitespace == (size_t) -1) + last_key_whitespace = n_key; + + if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) { + r = -ENOMEM; + goto fail; + } + + key[n_key++] = c; + } + + break; + + case PRE_VALUE: + if (strchr(newline, c)) { + state = PRE_KEY; + line ++; + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + + n_key = 0; + value = NULL; + value_alloc = n_value = 0; + + } else if (c == '\'') + state = SINGLE_QUOTE_VALUE; + else if (c == '\"') + state = DOUBLE_QUOTE_VALUE; + else if (c == '\\') + state = VALUE_ESCAPE; + else if (!strchr(WHITESPACE, c)) { + state = VALUE; + + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + + break; + + case VALUE: + if (strchr(newline, c)) { + state = PRE_KEY; + line ++; + + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + /* Chomp off trailing whitespace from value */ + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + + n_key = 0; + value = NULL; + value_alloc = n_value = 0; + + } else if (c == '\\') { + state = VALUE_ESCAPE; + last_value_whitespace = (size_t) -1; + } else { + if (!strchr(WHITESPACE, c)) + last_value_whitespace = (size_t) -1; + else if (last_value_whitespace == (size_t) -1) + last_value_whitespace = n_value; + + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + + break; + + case VALUE_ESCAPE: + state = VALUE; + + if (!strchr(newline, c)) { + /* Escaped newlines we eat up entirely */ + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + break; + + case SINGLE_QUOTE_VALUE: + if (c == '\'') + state = PRE_VALUE; + else if (c == '\\') + state = SINGLE_QUOTE_VALUE_ESCAPE; + else { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + + break; + + case SINGLE_QUOTE_VALUE_ESCAPE: + state = SINGLE_QUOTE_VALUE; + + if (!strchr(newline, c)) { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + break; + + case DOUBLE_QUOTE_VALUE: + if (c == '\"') + state = PRE_VALUE; + else if (c == '\\') + state = DOUBLE_QUOTE_VALUE_ESCAPE; + else { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + + break; + + case DOUBLE_QUOTE_VALUE_ESCAPE: + state = DOUBLE_QUOTE_VALUE; + + if (!strchr(newline, c)) { + if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) { + r = -ENOMEM; + goto fail; + } + + value[n_value++] = c; + } + break; + + case COMMENT: + if (c == '\\') + state = COMMENT_ESCAPE; + else if (strchr(newline, c)) { + state = PRE_KEY; + line ++; + } + break; + + case COMMENT_ESCAPE: + state = COMMENT; + break; + } + } + + if (state == PRE_VALUE || + state == VALUE || + state == VALUE_ESCAPE || + state == SINGLE_QUOTE_VALUE || + state == SINGLE_QUOTE_VALUE_ESCAPE || + state == DOUBLE_QUOTE_VALUE || + state == DOUBLE_QUOTE_VALUE_ESCAPE) { + + key[n_key] = 0; + + if (value) + value[n_value] = 0; + + if (state == VALUE) + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + + r = push(fname, line, key, value, userdata, n_pushed); + if (r < 0) + goto fail; + } + + return 0; + +fail: + free(value); + return r; +} + +static int parse_env_file_push( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + + const char *k; + va_list aq, *ap = userdata; + + if (!utf8_is_valid(key)) { + _cleanup_free_ char *p = utf8_escape_invalid(key); + + log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p); + return -EINVAL; + } + + if (value && !utf8_is_valid(value)) { + _cleanup_free_ char *p = utf8_escape_invalid(value); + + log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p); + return -EINVAL; + } + + va_copy(aq, *ap); + + while ((k = va_arg(aq, const char *))) { + char **v; + + v = va_arg(aq, char **); + + if (streq(key, k)) { + va_end(aq); + free(*v); + *v = value; + + if (n_pushed) + (*n_pushed)++; + + return 1; + } + } + + va_end(aq); + free(value); + + return 0; +} + +int parse_env_file( + const char *fname, + const char *newline, ...) { + + va_list ap; + int r, n_pushed = 0; + + if (!newline) + newline = NEWLINE; + + va_start(ap, newline); + r = parse_env_file_internal(NULL, fname, newline, parse_env_file_push, &ap, &n_pushed); + va_end(ap); + + return r < 0 ? r : n_pushed; +} + +static int load_env_file_push( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + char ***m = userdata; + char *p; + int r; + + if (!utf8_is_valid(key)) { + _cleanup_free_ char *t = utf8_escape_invalid(key); + + log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t); + return -EINVAL; + } + + if (value && !utf8_is_valid(value)) { + _cleanup_free_ char *t = utf8_escape_invalid(value); + + log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t); + return -EINVAL; + } + + p = strjoin(key, "=", strempty(value), NULL); + if (!p) + return -ENOMEM; + + r = strv_consume(m, p); + if (r < 0) + return r; + + if (n_pushed) + (*n_pushed)++; + + free(value); + return 0; +} + +int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) { + char **m = NULL; + int r; + + if (!newline) + newline = NEWLINE; + + r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL); + if (r < 0) { + strv_free(m); + return r; + } + + *rl = m; + return 0; +} + +static int load_env_file_push_pairs( + const char *filename, unsigned line, + const char *key, char *value, + void *userdata, + int *n_pushed) { + char ***m = userdata; + int r; + + if (!utf8_is_valid(key)) { + _cleanup_free_ char *t = utf8_escape_invalid(key); + + log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t); + return -EINVAL; + } + + if (value && !utf8_is_valid(value)) { + _cleanup_free_ char *t = utf8_escape_invalid(value); + + log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t); + return -EINVAL; + } + + r = strv_extend(m, key); + if (r < 0) + return -ENOMEM; + + if (!value) { + r = strv_extend(m, ""); + if (r < 0) + return -ENOMEM; + } else { + r = strv_push(m, value); + if (r < 0) + return r; + } + + if (n_pushed) + (*n_pushed)++; + + return 0; +} + +int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) { + char **m = NULL; + int r; + + if (!newline) + newline = NEWLINE; + + r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL); + if (r < 0) { + strv_free(m); + return r; + } + + *rl = m; + return 0; +} + +static void write_env_var(FILE *f, const char *v) { + const char *p; + + p = strchr(v, '='); + if (!p) { + /* Fallback */ + fputs(v, f); + fputc('\n', f); + return; + } + + p++; + fwrite(v, 1, p-v, f); + + if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) { + fputc('\"', f); + + for (; *p; p++) { + if (strchr(SHELL_NEED_ESCAPE, *p)) + fputc('\\', f); + + fputc(*p, f); + } + + fputc('\"', f); + } else + fputs(p, f); + + fputc('\n', f); +} + +int write_env_file(const char *fname, char **l) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + char **i; + int r; + + assert(fname); + + r = fopen_temporary(fname, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + STRV_FOREACH(i, l) + write_env_var(f, *i); + + r = fflush_and_check(f); + if (r >= 0) { + if (rename(p, fname) >= 0) + return 0; + + r = -errno; + } + + unlink(p); + return r; +} + +int executable_is_script(const char *path, char **interpreter) { + int r; + _cleanup_free_ char *line = NULL; + int len; + char *ans; + + assert(path); + + r = read_one_line_file(path, &line); + if (r < 0) + return r; + + if (!startswith(line, "#!")) + return 0; + + ans = strstrip(line + 2); + len = strcspn(ans, " \t"); + + if (len == 0) + return 0; + + ans = strndup(ans, len); + if (!ans) + return -ENOMEM; + + *interpreter = ans; + return 1; +} + +/** + * Retrieve one field from a file like /proc/self/status. pattern + * should start with '\n' and end with a ':'. Whitespace and zeros + * after the ':' will be skipped. field must be freed afterwards. + */ +int get_status_field(const char *filename, const char *pattern, char **field) { + _cleanup_free_ char *status = NULL; + char *t; + size_t len; + int r; + + assert(filename); + assert(pattern); + assert(field); + + r = read_full_file(filename, &status, NULL); + if (r < 0) + return r; + + t = strstr(status, pattern); + if (!t) + return -ENOENT; + + t += strlen(pattern); + if (*t) { + t += strspn(t, " \t"); + + /* Also skip zeros, because when this is used for + * capabilities, we don't want the zeros. This way the + * same capability set always maps to the same string, + * irrespective of the total capability set size. For + * other numbers it shouldn't matter. */ + t += strspn(t, "0"); + /* Back off one char if there's nothing but whitespace + and zeros */ + if (!*t || isspace(*t)) + t --; + } + + len = strcspn(t, WHITESPACE); + + *field = strndup(t, len); + if (!*field) + return -ENOMEM; + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h new file mode 100644 index 00000000..5ae51c1e --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h @@ -0,0 +1,45 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ +#include +#include + +#include "macro.h" + +int write_string_stream(FILE *f, const char *line); +int write_string_file(const char *fn, const char *line); +int write_string_file_no_create(const char *fn, const char *line); +int write_string_file_atomic(const char *fn, const char *line); + +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); +int read_full_stream(FILE *f, char **contents, size_t *size); + +int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; +int load_env_file(FILE *f, const char *fname, const char *separator, char ***l); +int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l); + +int write_env_file(const char *fname, char **l); + +int executable_is_script(const char *path, char **interpreter); + +int get_status_field(const char *filename, const char *pattern, char **field); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c new file mode 100644 index 00000000..27edeb8d --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c @@ -0,0 +1,294 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 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 . +***/ + +#include "config.h" + +#include + +#include "in-addr-util.h" + +int in_addr_is_null(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return u->in.s_addr == 0; + + if (family == AF_INET6) + return + u->in6.s6_addr32[0] == 0 && + u->in6.s6_addr32[1] == 0 && + u->in6.s6_addr32[2] == 0 && + u->in6.s6_addr32[3] == 0; + + return -EAFNOSUPPORT; +} + +int in_addr_is_link_local(int family, const union in_addr_union *u) { + assert(u); + + if (family == AF_INET) + return (be32toh(u->in.s_addr) & 0xFFFF0000) == (169U << 24 | 254U << 16); + + if (family == AF_INET6) + return IN6_IS_ADDR_LINKLOCAL(&u->in6); + + return -EAFNOSUPPORT; +} + +int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) { + assert(a); + assert(b); + + if (family == AF_INET) + return a->in.s_addr == b->in.s_addr; + + if (family == AF_INET6) + return + a->in6.s6_addr32[0] == b->in6.s6_addr32[0] && + a->in6.s6_addr32[1] == b->in6.s6_addr32[1] && + a->in6.s6_addr32[2] == b->in6.s6_addr32[2] && + a->in6.s6_addr32[3] == b->in6.s6_addr32[3]; + + return -EAFNOSUPPORT; +} + +int in_addr_prefix_intersect( + int family, + const union in_addr_union *a, + unsigned aprefixlen, + const union in_addr_union *b, + unsigned bprefixlen) { + + unsigned m; + + assert(a); + assert(b); + + /* Checks whether there are any addresses that are in both + * networks */ + + m = MIN(aprefixlen, bprefixlen); + + if (family == AF_INET) { + uint32_t x, nm; + + x = be32toh(a->in.s_addr ^ b->in.s_addr); + nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m); + + return (x & nm) == 0; + } + + if (family == AF_INET6) { + unsigned i; + + if (m > 128) + m = 128; + + for (i = 0; i < 16; i++) { + uint8_t x, nm; + + x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i]; + + if (m < 8) + nm = 0xFF << (8 - m); + else + nm = 0xFF; + + if ((x & nm) != 0) + return 0; + + if (m > 8) + m -= 8; + else + m = 0; + } + + return 1; + } + + return -EAFNOSUPPORT; +} + +int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) { + assert(u); + + /* Increases the network part of an address by one. Returns + * positive it that succeeds, or 0 if this overflows. */ + + if (prefixlen <= 0) + return 0; + + if (family == AF_INET) { + uint32_t c, n; + + if (prefixlen > 32) + prefixlen = 32; + + c = be32toh(u->in.s_addr); + n = c + (1UL << (32 - prefixlen)); + if (n < c) + return 0; + n &= 0xFFFFFFFFUL << (32 - prefixlen); + + u->in.s_addr = htobe32(n); + return 1; + } + + if (family == AF_INET6) { + struct in6_addr add = {}, result; + uint8_t overflow = 0; + unsigned i; + + if (prefixlen > 128) + prefixlen = 128; + + /* First calculate what we have to add */ + add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8); + + for (i = 16; i > 0; i--) { + unsigned j = i - 1; + + result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow; + overflow = (result.s6_addr[j] < u->in6.s6_addr[j]); + } + + if (overflow) + return 0; + + u->in6 = result; + return 1; + } + + return -EAFNOSUPPORT; +} + +int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { + char *x; + size_t l; + + assert(u); + assert(ret); + + if (family == AF_INET) + l = INET_ADDRSTRLEN; + else if (family == AF_INET6) + l = INET6_ADDRSTRLEN; + else + return -EAFNOSUPPORT; + + x = new(char, l); + if (!x) + return -ENOMEM; + + errno = 0; + if (!inet_ntop(family, u, x, l)) { + free(x); + return errno ? -errno : -EINVAL; + } + + *ret = x; + return 0; +} + +int in_addr_from_string(int family, const char *s, union in_addr_union *ret) { + + assert(s); + assert(ret); + + if (!IN_SET(family, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; + + errno = 0; + if (inet_pton(family, s, ret) <= 0) + return errno ? -errno : -EINVAL; + + return 0; +} + +int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret) { + int r; + + assert(s); + assert(family); + assert(ret); + + r = in_addr_from_string(AF_INET, s, ret); + if (r >= 0) { + *family = AF_INET; + return 0; + } + + r = in_addr_from_string(AF_INET6, s, ret); + if (r >= 0) { + *family = AF_INET6; + return 0; + } + + return -EINVAL; +} + +unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr) { + assert(addr); + + return 32 - u32ctz(be32toh(addr->s_addr)); +} + +int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) { + uint8_t msb_octet = *(uint8_t*) addr; + + /* addr may not be aligned, so make sure we only access it byte-wise */ + + assert(addr); + assert(prefixlen); + + if (msb_octet < 128) + /* class A, leading bits: 0 */ + *prefixlen = 8; + else if (msb_octet < 192) + /* class B, leading bits 10 */ + *prefixlen = 16; + else if (msb_octet < 224) + /* class C, leading bits 110 */ + *prefixlen = 24; + else + /* class D or E, no default prefixlen */ + return -ERANGE; + + return 0; +} + +int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) { + unsigned char prefixlen; + int r; + + assert(addr); + assert(mask); + + r = in_addr_default_prefixlen(addr, &prefixlen); + if (r < 0) + return r; + + assert(prefixlen > 0 && prefixlen < 32); + + mask->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff); + + return 0; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h new file mode 100644 index 00000000..8da030ce --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h @@ -0,0 +1,49 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 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 . +***/ + +#include + +#include "macro.h" +#include "util.h" + +union in_addr_union { + struct in_addr in; + struct in6_addr in6; +}; + +int in_addr_is_null(int family, const union in_addr_union *u); +int in_addr_is_link_local(int family, const union in_addr_union *u); +int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); +int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); +int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); +int in_addr_to_string(int family, const union in_addr_union *u, char **ret); +int in_addr_from_string(int family, const char *s, union in_addr_union *ret); +int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret); +unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr); +int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); +int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask); + +static inline size_t FAMILY_ADDRESS_SIZE(int family) { + assert(family == AF_INET || family == AF_INET6); + return family == AF_INET6 ? 16 : 4; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/list.h b/src/dhcp-manager/systemd-dhcp/src/shared/list.h new file mode 100644 index 00000000..c020f7e9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/list.h @@ -0,0 +1,138 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +/* The head of the linked list. Use this in the structure that shall + * contain the head of the linked list */ +#define LIST_HEAD(t,name) \ + t *name + +/* The pointers in the linked list's items. Use this in the item structure */ +#define LIST_FIELDS(t,name) \ + t *name##_next, *name##_prev + +/* Initialize the list's head */ +#define LIST_HEAD_INIT(head) \ + do { \ + (head) = NULL; } \ + while(false) + +/* Initialize a list item */ +#define LIST_INIT(name,item) \ + do { \ + typeof(*(item)) *_item = (item); \ + assert(_item); \ + _item->name##_prev = _item->name##_next = NULL; \ + } while(false) + +/* Prepend an item to the list */ +#define LIST_PREPEND(name,head,item) \ + do { \ + typeof(*(head)) **_head = &(head), *_item = (item); \ + assert(_item); \ + if ((_item->name##_next = *_head)) \ + _item->name##_next->name##_prev = _item; \ + _item->name##_prev = NULL; \ + *_head = _item; \ + } while(false) + +/* Remove an item from the list */ +#define LIST_REMOVE(name,head,item) \ + do { \ + typeof(*(head)) **_head = &(head), *_item = (item); \ + assert(_item); \ + if (_item->name##_next) \ + _item->name##_next->name##_prev = _item->name##_prev; \ + if (_item->name##_prev) \ + _item->name##_prev->name##_next = _item->name##_next; \ + else { \ + assert(*_head == _item); \ + *_head = _item->name##_next; \ + } \ + _item->name##_next = _item->name##_prev = NULL; \ + } while(false) + +/* Find the head of the list */ +#define LIST_FIND_HEAD(name,item,head) \ + do { \ + typeof(*(item)) *_item = (item); \ + if (!_item) \ + (head) = NULL; \ + else { \ + while (_item->name##_prev) \ + _item = _item->name##_prev; \ + (head) = _item; \ + } \ + } while (false) + +/* Find the tail of the list */ +#define LIST_FIND_TAIL(name,item,tail) \ + do { \ + typeof(*(item)) *_item = (item); \ + if (!_item) \ + (tail) = NULL; \ + else { \ + while (_item->name##_next) \ + _item = _item->name##_next; \ + (tail) = _item; \ + } \ + } while (false) + +/* Insert an item after another one (a = where, b = what) */ +#define LIST_INSERT_AFTER(name,head,a,b) \ + do { \ + typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \ + assert(_b); \ + if (!_a) { \ + if ((_b->name##_next = *_head)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->name##_next = _a->name##_next)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = _a; \ + _a->name##_next = _b; \ + } \ + } while(false) + +#define LIST_JUST_US(name,item) \ + (!(item)->name##_prev && !(item)->name##_next) \ + +#define LIST_FOREACH(name,i,head) \ + for ((i) = (head); (i); (i) = (i)->name##_next) + +#define LIST_FOREACH_SAFE(name,i,n,head) \ + for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +#define LIST_FOREACH_BEFORE(name,i,p) \ + for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) + +#define LIST_FOREACH_AFTER(name,i,p) \ + for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) + +/* Loop starting from p->next until p->prev. + p can be adjusted meanwhile. */ +#define LIST_LOOP_BUT_ONE(name,i,head,p) \ + for ((i) = (p)->name##_next ? (p)->name##_next : (head); \ + (i) != (p); \ + (i) = (i)->name##_next ? (i)->name##_next : (head)) diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/macro.h b/src/dhcp-manager/systemd-dhcp/src/shared/macro.h new file mode 100644 index 00000000..e6cf6eec --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/macro.h @@ -0,0 +1,413 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include +#include + +#define _printf_(a,b) __attribute__ ((format (printf, a, b))) +#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__))) +#define _sentinel_ __attribute__ ((sentinel)) +#define _unused_ __attribute__ ((unused)) +#define _destructor_ __attribute__ ((destructor)) +#define _pure_ __attribute__ ((pure)) +#define _const_ __attribute__ ((const)) +#define _deprecated_ __attribute__ ((deprecated)) +#define _packed_ __attribute__ ((packed)) +#define _malloc_ __attribute__ ((malloc)) +#define _weak_ __attribute__ ((weak)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) +#define _public_ __attribute__ ((visibility("default"))) +#define _hidden_ __attribute__ ((visibility("hidden"))) +#define _weakref_(x) __attribute__((weakref(#x))) +#define _alignas_(x) __attribute__((aligned(__alignof(x)))) +#define _cleanup_(x) __attribute__((cleanup(x))) + +/* Temporarily disable some warnings */ +#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") + +#define DISABLE_WARNING_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") + +#define DISABLE_WARNING_MISSING_PROTOTYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") + +#define DISABLE_WARNING_NONNULL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wnonnull\"") + +#define DISABLE_WARNING_SHADOW \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wshadow\"") + +#define REENABLE_WARNING \ + _Pragma("GCC diagnostic pop") + +/* automake test harness */ +#define EXIT_TEST_SKIP 77 + +#define XSTRINGIFY(x) #x +#define STRINGIFY(x) XSTRINGIFY(x) + +#define XCONCATENATE(x, y) x ## y +#define CONCATENATE(x, y) XCONCATENATE(x, y) + +#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq)) +#define UNIQ __COUNTER__ + +/* Rounds up */ + +#define ALIGN4(l) (((l) + 3) & ~3) +#define ALIGN8(l) (((l) + 7) & ~7) + +#if __SIZEOF_POINTER__ == 8 +#define ALIGN(l) ALIGN8(l) +#elif __SIZEOF_POINTER__ == 4 +#define ALIGN(l) ALIGN4(l) +#else +#error "Wut? Pointers are neither 4 nor 8 bytes long?" +#endif + +#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) p)) +#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) p)) +#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) p)) + +static inline size_t ALIGN_TO(size_t l, size_t ali) { + return ((l + ali - 1) & ~(ali - 1)); +} + +#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali)) + +/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */ +static inline unsigned long ALIGN_POWER2(unsigned long u) { + /* clz(0) is undefined */ + if (u == 1) + return 1; + + /* left-shift overflow is undefined */ + if (__builtin_clzl(u - 1UL) < 1) + return 0; + + return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL)); +} + +#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) + +/* + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member) +#define __container_of(uniq, ptr, type, member) \ + __extension__ ({ \ + const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \ + (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \ + }) + +#undef MAX +#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b)) +#define __MAX(aq, a, bq, b) \ + __extension__ ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ + }) + +/* evaluates to (void) if _A or _B are not constant or of different types */ +#define CONST_MAX(_A, _B) \ + __extension__ (__builtin_choose_expr( \ + __builtin_constant_p(_A) && \ + __builtin_constant_p(_B) && \ + __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ + ((_A) > (_B)) ? (_A) : (_B), \ + (void)0)) + +/* takes two types and returns the size of the larger one */ +#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; })) + +#define MAX3(x,y,z) \ + __extension__ ({ \ + const typeof(x) _c = MAX(x,y); \ + MAX(_c, z); \ + }) + +#undef MIN +#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b)) +#define __MIN(aq, a, bq, b) \ + __extension__ ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ + }) + +#define MIN3(x,y,z) \ + __extension__ ({ \ + const typeof(x) _c = MIN(x,y); \ + MIN(_c, z); \ + }) + +#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b)) +#define __LESS_BY(aq, a, bq, b) \ + __extension__ ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \ + }) + +#undef CLAMP +#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) +#define __CLAMP(xq, x, lowq, low, highq, high) \ + __extension__ ({ \ + const typeof(x) UNIQ_T(X,xq) = (x); \ + const typeof(low) UNIQ_T(LOW,lowq) = (low); \ + const typeof(high) UNIQ_T(HIGH,highq) = (high); \ + UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \ + UNIQ_T(HIGH,highq) : \ + UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \ + UNIQ_T(LOW,lowq) : \ + UNIQ_T(X,xq); \ + }) + +#define assert_se(expr) \ + do { \ + if (_unlikely_(!(expr))) \ + log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) \ + +/* We override the glibc assert() here. */ +#undef assert +#ifdef NDEBUG +#define assert(expr) do {} while(false) +#else +#define assert(expr) assert_se(expr) +#endif + +#define assert_not_reached(t) \ + do { \ + log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) + +#if defined(static_assert) +/* static_assert() is sometimes defined in a way that trips up + * -Wdeclaration-after-statement, hence let's temporarily turn off + * this warning around it. */ +#define assert_cc(expr) \ + DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ + static_assert(expr, #expr); \ + REENABLE_WARNING +#else +#define assert_cc(expr) \ + DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ + struct CONCATENATE(_assert_struct_, __LINE__) { \ + char x[(expr) ? 0 : -1]; \ + }; \ + REENABLE_WARNING +#endif + +#define assert_return(expr, r) \ + do { \ + if (_unlikely_(!(expr))) { \ + log_assert_failed_return(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + return (r); \ + } \ + } while (false) + +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) +#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) +#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p))) +#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p))) +#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p))) +#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define memzero(x,l) (memset((x), 0, (l))) +#define zero(x) (memzero(&(x), sizeof(x))) + +#define CHAR_TO_STR(x) ((char[2]) { x, 0 }) + +#define char_array_0(x) x[sizeof(x)-1] = 0; + +#define IOVEC_SET_STRING(i, s) \ + do { \ + struct iovec *_i = &(i); \ + char *_s = (char *)(s); \ + _i->iov_base = _s; \ + _i->iov_len = strlen(_s); \ + } while(false) + +static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) { + unsigned j; + size_t r = 0; + + for (j = 0; j < n; j++) + r += i[j].iov_len; + + return r; +} + +static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { + unsigned j; + + for (j = 0; j < n; j++) { + size_t sub; + + if (_unlikely_(k <= 0)) + break; + + sub = MIN(i[j].iov_len, k); + i[j].iov_len -= sub; + i[j].iov_base = (uint8_t*) i[j].iov_base + sub; + k -= sub; + } + + return k; +} + +#define VA_FORMAT_ADVANCE(format, ap) \ +do { \ + int _argtypes[128]; \ + size_t _i, _k; \ + _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \ + assert(_k < ELEMENTSOF(_argtypes)); \ + for (_i = 0; _i < _k; _i++) { \ + if (_argtypes[_i] & PA_FLAG_PTR) { \ + (void) va_arg(ap, void*); \ + continue; \ + } \ + \ + switch (_argtypes[_i]) { \ + case PA_INT: \ + case PA_INT|PA_FLAG_SHORT: \ + case PA_CHAR: \ + (void) va_arg(ap, int); \ + break; \ + case PA_INT|PA_FLAG_LONG: \ + (void) va_arg(ap, long int); \ + break; \ + case PA_INT|PA_FLAG_LONG_LONG: \ + (void) va_arg(ap, long long int); \ + break; \ + case PA_WCHAR: \ + (void) va_arg(ap, wchar_t); \ + break; \ + case PA_WSTRING: \ + case PA_STRING: \ + case PA_POINTER: \ + (void) va_arg(ap, void*); \ + break; \ + case PA_FLOAT: \ + case PA_DOUBLE: \ + (void) va_arg(ap, double); \ + break; \ + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \ + (void) va_arg(ap, long double); \ + break; \ + default: \ + assert_not_reached("Unknown format string argument."); \ + } \ + } \ +} while(false) + + /* Because statfs.t_type can be int on some architectures, we have to cast + * the const magic to the type, otherwise the compiler warns about + * signed/unsigned comparison, because the magic can be 32 bit unsigned. + */ +#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) + +/* Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix. */ +#define DECIMAL_STR_MAX(type) \ + (2+(sizeof(type) <= 1 ? 3 : \ + sizeof(type) <= 2 ? 5 : \ + sizeof(type) <= 4 ? 10 : \ + sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + +#define SET_FLAG(v, flag, b) \ + (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) + +#define IN_SET(x, y, ...) \ + ({ \ + const typeof(y) _y = (y); \ + typeof(_y) _x = (x); \ + unsigned _i; \ + bool _found = false; \ + for (_i = 0; _i < 1 + sizeof((typeof(_x)[]) { __VA_ARGS__ })/sizeof(typeof(_x)); _i++) \ + if (((typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \ + _found = true; \ + break; \ + } \ + _found; \ + }) + +#if 0 /* NM_IGNORED */ +/* Define C11 thread_local attribute even on older gcc compiler + * version */ +#ifndef thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define thread_local _Thread_local +#else +#define thread_local __thread +#endif +#endif + +/* Define C11 noreturn without and even on older gcc + * compiler versions */ +#ifndef noreturn +#if __STDC_VERSION__ >= 201112L +#define noreturn _Noreturn +#else +#define noreturn __attribute__((noreturn)) +#endif +#endif + +#include "log.h" +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h b/src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h new file mode 100644 index 00000000..0502c20a --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 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 . +***/ + +/* A type-safe atomic refcounter */ + +typedef struct { + volatile unsigned _value; +} RefCount; + +#define REFCNT_GET(r) ((r)._value) +#define REFCNT_INC(r) (__sync_add_and_fetch(&(r)._value, 1)) +#define REFCNT_DEC(r) (__sync_sub_and_fetch(&(r)._value, 1)) + +#define REFCNT_INIT ((RefCount) { ._value = 1 }) diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c b/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c new file mode 100644 index 00000000..f9e59c6f --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c @@ -0,0 +1,137 @@ +/* + SipHash reference C implementation + + Written in 2012 by + Jean-Philippe Aumasson + Daniel J. Bernstein + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . + + (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd) +*/ +#include "config.h" + +#include +#include +#include + +#include "siphash24.h" + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint8_t u8; + +#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) ) + +#define U32TO8_LE(p, v) \ + (p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \ + (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24); + +#define U64TO8_LE(p, v) \ + U32TO8_LE((p), (u32)((v) )); \ + U32TO8_LE((p) + 4, (u32)((v) >> 32)); + +#define U8TO64_LE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) + +#define SIPROUND \ + do { \ + v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \ + v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \ + v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \ + v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \ + } while(0) + +/* SipHash-2-4 */ +void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) +{ + /* "somepseudorandomlygeneratedbytes" */ + u64 v0 = 0x736f6d6570736575ULL; + u64 v1 = 0x646f72616e646f6dULL; + u64 v2 = 0x6c7967656e657261ULL; + u64 v3 = 0x7465646279746573ULL; + u64 b; + u64 k0 = U8TO64_LE( k ); + u64 k1 = U8TO64_LE( k + 8 ); + u64 m; + const u8 *in = _in; + const u8 *end = in + inlen - ( inlen % sizeof( u64 ) ); + const int left = inlen & 7; + b = ( ( u64 )inlen ) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + + for ( ; in != end; in += 8 ) + { + m = U8TO64_LE( in ); +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m ); +#endif + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + + switch( left ) + { + case 7: b |= ( ( u64 )in[ 6] ) << 48; + + case 6: b |= ( ( u64 )in[ 5] ) << 40; + + case 5: b |= ( ( u64 )in[ 4] ) << 32; + + case 4: b |= ( ( u64 )in[ 3] ) << 24; + + case 3: b |= ( ( u64 )in[ 2] ) << 16; + + case 2: b |= ( ( u64 )in[ 1] ) << 8; + + case 1: b |= ( ( u64 )in[ 0] ); break; + + case 0: break; + } + +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b ); +#endif + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); +#endif + v2 ^= 0xff; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + U64TO8_LE( out, b ); +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h b/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h new file mode 100644 index 00000000..62e1168a --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h b/src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h new file mode 100644 index 00000000..07d0aff7 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h @@ -0,0 +1,118 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_nl nl; + struct sockaddr_storage storage; + struct sockaddr_ll ll; +}; + +typedef struct SocketAddress { + union sockaddr_union sockaddr; + + /* We store the size here explicitly due to the weird + * sockaddr_un semantics for abstract sockets */ + socklen_t size; + + /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */ + int type; + + /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */ + int protocol; +} SocketAddress; + +typedef enum SocketAddressBindIPv6Only { + SOCKET_ADDRESS_DEFAULT, + SOCKET_ADDRESS_BOTH, + SOCKET_ADDRESS_IPV6_ONLY, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1 +} SocketAddressBindIPv6Only; + +#define socket_address_family(a) ((a)->sockaddr.sa.sa_family) + +int socket_address_parse(SocketAddress *a, const char *s); +int socket_address_parse_netlink(SocketAddress *a, const char *s); +int socket_address_print(const SocketAddress *a, char **p); +int socket_address_verify(const SocketAddress *a) _pure_; +int socket_address_unlink(SocketAddress *a); + +bool socket_address_can_accept(const SocketAddress *a) _pure_; + +int socket_address_listen( + const SocketAddress *a, + int flags, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label); +int make_socket_fd(int log_level, const char* address, int flags); + +bool socket_address_is(const SocketAddress *a, const char *s, int type); +bool socket_address_is_netlink(const SocketAddress *a, const char *s); + +bool socket_address_matches_fd(const SocketAddress *a, int fd); + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_; + +const char* socket_address_get_path(const SocketAddress *a); + +bool socket_ipv6_is_supported(void); + +int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret); +int getpeername_pretty(int fd, char **ret); +int getsockname_pretty(int fd, char **ret); + +int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret); +int getnameinfo_pretty(int fd, char **ret); + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; + +int netlink_family_to_string_alloc(int b, char **s); +int netlink_family_from_string(const char *s) _pure_; + +bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b); + +#define ETHER_ADDR_TO_STRING_MAX (3*6) + +char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h b/src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h new file mode 100644 index 00000000..c913fda8 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2012 Josh Triplett + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef SPARSE_ENDIAN_H +#define SPARSE_ENDIAN_H + +#include +#include +#include + +#ifdef __CHECKER__ +#define __bitwise __attribute__((bitwise)) +#define __force __attribute__((force)) +#else +#define __bitwise +#define __force +#endif + +typedef uint16_t __bitwise le16_t; +typedef uint16_t __bitwise be16_t; +typedef uint32_t __bitwise le32_t; +typedef uint32_t __bitwise be32_t; +typedef uint64_t __bitwise le64_t; +typedef uint64_t __bitwise be64_t; + +#undef htobe16 +#undef htole16 +#undef be16toh +#undef le16toh +#undef htobe32 +#undef htole32 +#undef be32toh +#undef le32toh +#undef htobe64 +#undef htole64 +#undef be64toh +#undef le64toh + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define bswap_16_on_le(x) __bswap_16(x) +#define bswap_32_on_le(x) __bswap_32(x) +#define bswap_64_on_le(x) __bswap_64(x) +#define bswap_16_on_be(x) (x) +#define bswap_32_on_be(x) (x) +#define bswap_64_on_be(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define bswap_16_on_le(x) (x) +#define bswap_32_on_le(x) (x) +#define bswap_64_on_le(x) (x) +#define bswap_16_on_be(x) __bswap_16(x) +#define bswap_32_on_be(x) __bswap_32(x) +#define bswap_64_on_be(x) __bswap_64(x) +#endif + +static inline le16_t htole16(uint16_t value) { return (le16_t __force) bswap_16_on_be(value); } +static inline le32_t htole32(uint32_t value) { return (le32_t __force) bswap_32_on_be(value); } +static inline le64_t htole64(uint64_t value) { return (le64_t __force) bswap_64_on_be(value); } + +static inline be16_t htobe16(uint16_t value) { return (be16_t __force) bswap_16_on_le(value); } +static inline be32_t htobe32(uint32_t value) { return (be32_t __force) bswap_32_on_le(value); } +static inline be64_t htobe64(uint64_t value) { return (be64_t __force) bswap_64_on_le(value); } + +static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __force)value); } +static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __force)value); } +static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __force)value); } + +static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __force)value); } +static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __force)value); } +static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __force)value); } + +#endif /* SPARSE_ENDIAN_H */ diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/strv.c b/src/dhcp-manager/systemd-dhcp/src/shared/strv.c new file mode 100644 index 00000000..be2bd511 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/strv.c @@ -0,0 +1,616 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" + +char *strv_find(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (streq(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_prefix(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (startswith(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_startswith(char **l, const char *name) { + char **i, *e; + + assert(name); + + /* Like strv_find_prefix, but actually returns only the + * suffix, not the whole item */ + + STRV_FOREACH(i, l) { + e = startswith(*i, name); + if (e) + return e; + } + + return NULL; +} + +void strv_free(char **l) { + char **k; + + if (!l) + return; + + for (k = l; *k; k++) + free(*k); + + free(l); +} + +char **strv_copy(char * const *l) { + char **r, **k; + + k = r = new(char*, strv_length(l) + 1); + if (!r) + return NULL; + + if (l) + for (; *l; k++, l++) { + *k = strdup(*l); + if (!*k) { + strv_free(r); + return NULL; + } + } + + *k = NULL; + return r; +} + +unsigned strv_length(char * const *l) { + unsigned n = 0; + + if (!l) + return 0; + + for (; *l; l++) + n++; + + return n; +} + +char **strv_new_ap(const char *x, va_list ap) { + const char *s; + char **a; + unsigned n = 0, i = 0; + va_list aq; + + /* As a special trick we ignore all listed strings that equal + * (const char*) -1. This is supposed to be used with the + * STRV_IFNOTNULL() macro to include possibly NULL strings in + * the string list. */ + + if (x) { + n = x == (const char*) -1 ? 0 : 1; + + va_copy(aq, ap); + while ((s = va_arg(aq, const char*))) { + if (s == (const char*) -1) + continue; + + n++; + } + + va_end(aq); + } + + a = new(char*, n+1); + if (!a) + return NULL; + + if (x) { + if (x != (const char*) -1) { + a[i] = strdup(x); + if (!a[i]) + goto fail; + i++; + } + + while ((s = va_arg(ap, const char*))) { + + if (s == (const char*) -1) + continue; + + a[i] = strdup(s); + if (!a[i]) + goto fail; + + i++; + } + } + + a[i] = NULL; + + return a; + +fail: + strv_free(a); + return NULL; +} + +char **strv_new(const char *x, ...) { + char **r; + va_list ap; + + va_start(ap, x); + r = strv_new_ap(x, ap); + va_end(ap); + + return r; +} + +int strv_extend_strv(char ***a, char **b) { + int r; + char **s; + + STRV_FOREACH(s, b) { + r = strv_extend(a, *s); + if (r < 0) + return r; + } + + return 0; +} + +int strv_extend_strv_concat(char ***a, char **b, const char *suffix) { + int r; + char **s; + + STRV_FOREACH(s, b) { + char *v; + + v = strappend(*s, suffix); + if (!v) + return -ENOMEM; + + r = strv_push(a, v); + if (r < 0) { + free(v); + return r; + } + } + + return 0; +} + +char **strv_split(const char *s, const char *separator) { + const char *word, *state; + size_t l; + unsigned n, i; + char **r; + + assert(s); + + n = 0; + FOREACH_WORD_SEPARATOR(word, l, s, separator, state) + n++; + + r = new(char*, n+1); + if (!r) + return NULL; + + i = 0; + FOREACH_WORD_SEPARATOR(word, l, s, separator, state) { + r[i] = strndup(word, l); + if (!r[i]) { + strv_free(r); + return NULL; + } + + i++; + } + + r[i] = NULL; + return r; +} + +char **strv_split_newlines(const char *s) { + char **l; + unsigned n; + + assert(s); + + /* Special version of strv_split() that splits on newlines and + * suppresses an empty string at the end */ + + l = strv_split(s, NEWLINE); + if (!l) + return NULL; + + n = strv_length(l); + if (n <= 0) + return l; + + if (isempty(l[n-1])) { + free(l[n-1]); + l[n-1] = NULL; + } + + return l; +} + +#if 0 /* NM_IGNORED */ +int strv_split_quoted(char ***t, const char *s, bool relax) { + size_t n = 0, allocated = 0; + _cleanup_strv_free_ char **l = NULL; + int r; + + assert(t); + assert(s); + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = unquote_first_word(&s, &word, relax); + if (r < 0) + return r; + if (r == 0) + break; + + if (!GREEDY_REALLOC(l, allocated, n + 2)) + return -ENOMEM; + + l[n++] = word; + word = NULL; + + l[n] = NULL; + } + + if (!l) + l = new0(char*, 1); + + *t = l; + l = NULL; + + return 0; +} +#endif + +char *strv_join(char **l, const char *separator) { + char *r, *e; + char **s; + size_t n, k; + + if (!separator) + separator = " "; + + k = strlen(separator); + + n = 0; + STRV_FOREACH(s, l) { + if (n != 0) + n += k; + n += strlen(*s); + } + + r = new(char, n+1); + if (!r) + return NULL; + + e = r; + STRV_FOREACH(s, l) { + if (e != r) + e = stpcpy(e, separator); + + e = stpcpy(e, *s); + } + + *e = 0; + + return r; +} + +char *strv_join_quoted(char **l) { + char *buf = NULL; + char **s; + size_t allocated = 0, len = 0; + + STRV_FOREACH(s, l) { + /* assuming here that escaped string cannot be more + * than twice as long, and reserving space for the + * separator and quotes. + */ + _cleanup_free_ char *esc = NULL; + size_t needed; + + if (!GREEDY_REALLOC(buf, allocated, + len + strlen(*s) * 2 + 3)) + goto oom; + + esc = cescape(*s); + if (!esc) + goto oom; + + needed = snprintf(buf + len, allocated - len, "%s\"%s\"", + len > 0 ? " " : "", esc); + assert(needed < allocated - len); + len += needed; + } + + if (!buf) + buf = malloc0(1); + + return buf; + + oom: + free(buf); + return NULL; +} + +int strv_push(char ***l, char *value) { + char **c; + unsigned n, m; + + if (!value) + return 0; + + n = strv_length(*l); + + /* increase and check for overflow */ + m = n + 2; + if (m < n) + return -ENOMEM; + + c = realloc_multiply(*l, sizeof(char*), m); + if (!c) + return -ENOMEM; + + c[n] = value; + c[n+1] = NULL; + + *l = c; + return 0; +} + +int strv_push_prepend(char ***l, char *value) { + char **c; + unsigned n, m, i; + + if (!value) + return 0; + + n = strv_length(*l); + + /* increase and check for overflow */ + m = n + 2; + if (m < n) + return -ENOMEM; + + c = new(char*, m); + if (!c) + return -ENOMEM; + + for (i = 0; i < n; i++) + c[i+1] = (*l)[i]; + + c[0] = value; + c[n+1] = NULL; + + free(*l); + *l = c; + + return 0; +} + +int strv_consume(char ***l, char *value) { + int r; + + r = strv_push(l, value); + if (r < 0) + free(value); + + return r; +} + +int strv_consume_prepend(char ***l, char *value) { + int r; + + r = strv_push_prepend(l, value); + if (r < 0) + free(value); + + return r; +} + +int strv_extend(char ***l, const char *value) { + char *v; + + if (!value) + return 0; + + v = strdup(value); + if (!v) + return -ENOMEM; + + return strv_consume(l, v); +} + +char **strv_uniq(char **l) { + char **i; + + /* Drops duplicate entries. The first identical string will be + * kept, the others dropped */ + + STRV_FOREACH(i, l) + strv_remove(i+1, *i); + + return l; +} + +char **strv_remove(char **l, const char *s) { + char **f, **t; + + if (!l) + return NULL; + + assert(s); + + /* Drops every occurrence of s in the string list, edits + * in-place. */ + + for (f = t = l; *f; f++) + if (streq(*f, s)) + free(*f); + else + *(t++) = *f; + + *t = NULL; + return l; +} + +char **strv_parse_nulstr(const char *s, size_t l) { + const char *p; + unsigned c = 0, i = 0; + char **v; + + assert(s || l <= 0); + + if (l <= 0) + return new0(char*, 1); + + for (p = s; p < s + l; p++) + if (*p == 0) + c++; + + if (s[l-1] != 0) + c++; + + v = new0(char*, c+1); + if (!v) + return NULL; + + p = s; + while (p < s + l) { + const char *e; + + e = memchr(p, 0, s + l - p); + + v[i] = strndup(p, e ? e - p : s + l - p); + if (!v[i]) { + strv_free(v); + return NULL; + } + + i++; + + if (!e) + break; + + p = e + 1; + } + + assert(i == c); + + return v; +} + +char **strv_split_nulstr(const char *s) { + const char *i; + char **r = NULL; + + NULSTR_FOREACH(i, s) + if (strv_extend(&r, i) < 0) { + strv_free(r); + return NULL; + } + + if (!r) + return strv_new(NULL, NULL); + + return r; +} + +bool strv_overlap(char **a, char **b) { + char **i; + + STRV_FOREACH(i, a) + if (strv_contains(b, *i)) + return true; + + return false; +} + +static int str_compare(const void *_a, const void *_b) { + const char **a = (const char**) _a, **b = (const char**) _b; + + return strcmp(*a, *b); +} + +char **strv_sort(char **l) { + + if (strv_isempty(l)) + return l; + + qsort(l, strv_length(l), sizeof(char*), str_compare); + return l; +} + +void strv_print(char **l) { + char **s; + + STRV_FOREACH(s, l) + puts(*s); +} + +int strv_extendf(char ***l, const char *format, ...) { + va_list ap; + char *x; + int r; + + va_start(ap, format); + r = vasprintf(&x, format, ap); + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return strv_consume(l, x); +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/strv.h b/src/dhcp-manager/systemd-dhcp/src/shared/strv.h new file mode 100644 index 00000000..47618bd2 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/strv.h @@ -0,0 +1,137 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +#include "util.h" + +char *strv_find(char **l, const char *name) _pure_; +char *strv_find_prefix(char **l, const char *name) _pure_; +char *strv_find_startswith(char **l, const char *name) _pure_; + +void strv_free(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); +#define _cleanup_strv_free_ _cleanup_(strv_freep) + +char **strv_copy(char * const *l); +unsigned strv_length(char * const *l) _pure_; + +int strv_extend_strv(char ***a, char **b); +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_push(char ***l, char *value); +int strv_push_prepend(char ***l, char *value); +int strv_consume(char ***l, char *value); +int strv_consume_prepend(char ***l, char *value); + +char **strv_remove(char **l, const char *s); +char **strv_uniq(char **l); + +#define strv_contains(l, s) (!!strv_find((l), (s))) + +char **strv_new(const char *x, ...) _sentinel_; +char **strv_new_ap(const char *x, va_list ap); + +static inline const char* STRV_IFNOTNULL(const char *x) { + return x ? x : (const char *) -1; +} + +static inline bool strv_isempty(char * const *l) { + return !l || !*l; +} + +char **strv_split(const char *s, const char *separator); +char **strv_split_newlines(const char *s); + +int strv_split_quoted(char ***t, const char *s, bool relax); + +char *strv_join(char **l, const char *separator); +char *strv_join_quoted(char **l); + +char **strv_parse_nulstr(const char *s, size_t l); +char **strv_split_nulstr(const char *s); + +bool strv_overlap(char **a, char **b) _pure_; + +#define STRV_FOREACH(s, l) \ + for ((s) = (l); (s) && *(s); (s)++) + +#define STRV_FOREACH_BACKWARDS(s, l) \ + STRV_FOREACH(s, l) \ + ; \ + for ((s)--; (l) && ((s) >= (l)); (s)--) + +#define STRV_FOREACH_PAIR(x, y, l) \ + for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1)) + +char **strv_sort(char **l); +void strv_print(char **l); + +#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL })) + +#define STRV_MAKE_EMPTY ((char*[1]) { NULL }) + +#define strv_from_stdarg_alloca(first) \ + ({ \ + char **_l; \ + \ + if (!first) \ + _l = (char**) &first; \ + else { \ + unsigned _n; \ + va_list _ap; \ + \ + _n = 1; \ + va_start(_ap, first); \ + while (va_arg(_ap, char*)) \ + _n++; \ + va_end(_ap); \ + \ + _l = newa(char*, _n+1); \ + _l[_n = 0] = (char*) first; \ + va_start(_ap, first); \ + for (;;) { \ + _l[++_n] = va_arg(_ap, char*); \ + if (!_l[_n]) \ + break; \ + } \ + va_end(_ap); \ + } \ + _l; \ + }) + +#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x) + +#define FOREACH_STRING(x, ...) \ + for (char **_l = ({ \ + char **_ll = STRV_MAKE(__VA_ARGS__); \ + x = _ll ? _ll[0] : NULL; \ + _ll; \ + }); \ + _l && *_l; \ + x = ({ \ + _l ++; \ + _l[0]; \ + })) diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/time-util.c b/src/dhcp-manager/systemd-dhcp/src/shared/time-util.c new file mode 100644 index 00000000..c8fa1acb --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/time-util.c @@ -0,0 +1,1003 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include + +#include "util.h" +#include "time-util.h" +#if 0 /* NM_IGNORED */ +#include "strv.h" +#endif + +usec_t now(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(clock_id, &ts) == 0); + + return timespec_load(&ts); +} + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + + return ts; +} + +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { + int64_t delta; + assert(ts); + + if (u == USEC_INFINITY || u <= 0) { + ts->realtime = ts->monotonic = u; + return ts; + } + + ts->realtime = u; + + delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; + ts->monotonic = now(CLOCK_MONOTONIC); + + if ((int64_t) ts->monotonic > delta) + ts->monotonic -= delta; + else + ts->monotonic = 0; + + return ts; +} + +dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) { + int64_t delta; + assert(ts); + + if (u == USEC_INFINITY) { + ts->realtime = ts->monotonic = USEC_INFINITY; + return ts; + } + + ts->monotonic = u; + delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u; + + ts->realtime = now(CLOCK_REALTIME); + if ((int64_t) ts->realtime > delta) + ts->realtime -= delta; + else + ts->realtime = 0; + + return ts; +} + +usec_t timespec_load(const struct timespec *ts) { + assert(ts); + + if (ts->tv_sec == (time_t) -1 && + ts->tv_nsec == (long) -1) + return USEC_INFINITY; + + if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC) + return USEC_INFINITY; + + return + (usec_t) ts->tv_sec * USEC_PER_SEC + + (usec_t) ts->tv_nsec / NSEC_PER_USEC; +} + +struct timespec *timespec_store(struct timespec *ts, usec_t u) { + assert(ts); + + if (u == USEC_INFINITY) { + ts->tv_sec = (time_t) -1; + ts->tv_nsec = (long) -1; + return ts; + } + + ts->tv_sec = (time_t) (u / USEC_PER_SEC); + ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC); + + return ts; +} + +#if 0 /* NM_IGNORED */ +usec_t timeval_load(const struct timeval *tv) { + assert(tv); + + if (tv->tv_sec == (time_t) -1 && + tv->tv_usec == (suseconds_t) -1) + return USEC_INFINITY; + + if ((usec_t) tv->tv_sec > (UINT64_MAX - tv->tv_usec) / USEC_PER_SEC) + return USEC_INFINITY; + + return + (usec_t) tv->tv_sec * USEC_PER_SEC + + (usec_t) tv->tv_usec; +} + +struct timeval *timeval_store(struct timeval *tv, usec_t u) { + assert(tv); + + if (u == USEC_INFINITY) { + tv->tv_sec = (time_t) -1; + tv->tv_usec = (suseconds_t) -1; + } else { + tv->tv_sec = (time_t) (u / USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC); + } + + return tv; +} + +static char *format_timestamp_internal(char *buf, size_t l, usec_t t, bool utc) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0 || t == USEC_INFINITY) + return NULL; + + sec = (time_t) (t / USEC_PER_SEC); + + if (utc) + gmtime_r(&sec, &tm); + else + localtime_r(&sec, &tm); + if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm) <= 0) + return NULL; + + return buf; +} + +char *format_timestamp(char *buf, size_t l, usec_t t) { + return format_timestamp_internal(buf, l, t, false); +} + +char *format_timestamp_utc(char *buf, size_t l, usec_t t) { + return format_timestamp_internal(buf, l, t, true); +} + +static char *format_timestamp_internal_us(char *buf, size_t l, usec_t t, bool utc) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0 || t == USEC_INFINITY) + return NULL; + + sec = (time_t) (t / USEC_PER_SEC); + if (utc) + gmtime_r(&sec, &tm); + else + localtime_r(&sec, &tm); + + if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0) + return NULL; + snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC)); + if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0) + return NULL; + + return buf; +} + +char *format_timestamp_us(char *buf, size_t l, usec_t t) { + return format_timestamp_internal_us(buf, l, t, false); +} + +char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) { + return format_timestamp_internal_us(buf, l, t, true); +} + +char *format_timestamp_relative(char *buf, size_t l, usec_t t) { + const char *s; + usec_t n, d; + + if (t <= 0 || t == USEC_INFINITY) + return NULL; + + n = now(CLOCK_REALTIME); + if (n > t) { + d = n - t; + s = "ago"; + } else { + d = t - n; + s = "left"; + } + + if (d >= USEC_PER_YEAR) + snprintf(buf, l, USEC_FMT " years " USEC_FMT " months %s", + d / USEC_PER_YEAR, + (d % USEC_PER_YEAR) / USEC_PER_MONTH, s); + else if (d >= USEC_PER_MONTH) + snprintf(buf, l, USEC_FMT " months " USEC_FMT " days %s", + d / USEC_PER_MONTH, + (d % USEC_PER_MONTH) / USEC_PER_DAY, s); + else if (d >= USEC_PER_WEEK) + snprintf(buf, l, USEC_FMT " weeks " USEC_FMT " days %s", + d / USEC_PER_WEEK, + (d % USEC_PER_WEEK) / USEC_PER_DAY, s); + else if (d >= 2*USEC_PER_DAY) + snprintf(buf, l, USEC_FMT " days %s", d / USEC_PER_DAY, s); + else if (d >= 25*USEC_PER_HOUR) + snprintf(buf, l, "1 day " USEC_FMT "h %s", + (d - USEC_PER_DAY) / USEC_PER_HOUR, s); + else if (d >= 6*USEC_PER_HOUR) + snprintf(buf, l, USEC_FMT "h %s", + d / USEC_PER_HOUR, s); + else if (d >= USEC_PER_HOUR) + snprintf(buf, l, USEC_FMT "h " USEC_FMT "min %s", + d / USEC_PER_HOUR, + (d % USEC_PER_HOUR) / USEC_PER_MINUTE, s); + else if (d >= 5*USEC_PER_MINUTE) + snprintf(buf, l, USEC_FMT "min %s", + d / USEC_PER_MINUTE, s); + else if (d >= USEC_PER_MINUTE) + snprintf(buf, l, USEC_FMT "min " USEC_FMT "s %s", + d / USEC_PER_MINUTE, + (d % USEC_PER_MINUTE) / USEC_PER_SEC, s); + else if (d >= USEC_PER_SEC) + snprintf(buf, l, USEC_FMT "s %s", + d / USEC_PER_SEC, s); + else if (d >= USEC_PER_MSEC) + snprintf(buf, l, USEC_FMT "ms %s", + d / USEC_PER_MSEC, s); + else if (d > 0) + snprintf(buf, l, USEC_FMT"us %s", + d, s); + else + snprintf(buf, l, "now"); + + buf[l-1] = 0; + return buf; +} +#endif + +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "y", USEC_PER_YEAR }, + { "month", USEC_PER_MONTH }, + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, + }; + + unsigned i; + char *p = buf; + bool something = false; + + assert(buf); + assert(l > 0); + + if (t == USEC_INFINITY) { + strncpy(p, "infinity", l-1); + p[l-1] = 0; + return p; + } + + if (t <= 0) { + strncpy(p, "0", l-1); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_sec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k = 0; + size_t n; + bool done = false; + usec_t a, b; + + if (t <= 0) + break; + + if (t < accuracy && something) + break; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + a = t / table[i].usec; + b = t % table[i].usec; + + /* Let's see if we should shows this in dot notation */ + if (t < USEC_PER_MINUTE && b > 0) { + usec_t cc; + int j; + + j = 0; + for (cc = table[i].usec; cc > 1; cc /= 10) + j++; + + for (cc = accuracy; cc > 1; cc /= 10) { + b /= 10; + j--; + } + + if (j > 0) { + k = snprintf(p, l, + "%s"USEC_FMT".%0*llu%s", + p > buf ? " " : "", + a, + j, + (unsigned long long) b, + table[i].suffix); + + t = 0; + done = true; + } + } + + /* No? Then let's show it normally */ + if (!done) { + k = snprintf(p, l, + "%s"USEC_FMT"%s", + p > buf ? " " : "", + a, + table[i].suffix); + + t = b; + } + + n = MIN((size_t) k, l); + + l -= n; + p += n; + + something = true; + } + + *p = 0; + + return buf; +} + +#if 0 /* NM_IGNORED */ +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) { + + assert(f); + assert(name); + assert(t); + + if (!dual_timestamp_is_set(t)) + return; + + fprintf(f, "%s="USEC_FMT" "USEC_FMT"\n", + name, + t->realtime, + t->monotonic); +} + +void dual_timestamp_deserialize(const char *value, dual_timestamp *t) { + unsigned long long a, b; + + assert(value); + assert(t); + + if (sscanf(value, "%llu %llu", &a, &b) != 2) + log_debug("Failed to parse finish timestamp value %s", value); + else { + t->realtime = a; + t->monotonic = b; + } +} + +int parse_timestamp(const char *t, usec_t *usec) { + static const struct { + const char *name; + const int nr; + } day_nr[] = { + { "Sunday", 0 }, + { "Sun", 0 }, + { "Monday", 1 }, + { "Mon", 1 }, + { "Tuesday", 2 }, + { "Tue", 2 }, + { "Wednesday", 3 }, + { "Wed", 3 }, + { "Thursday", 4 }, + { "Thu", 4 }, + { "Friday", 5 }, + { "Fri", 5 }, + { "Saturday", 6 }, + { "Sat", 6 }, + }; + + const char *k; + struct tm tm, copy; + time_t x; + usec_t plus = 0, minus = 0, ret; + int r, weekday = -1; + unsigned i; + + /* + * Allowed syntaxes: + * + * 2012-09-22 16:34:22 + * 2012-09-22 16:34 (seconds will be set to 0) + * 2012-09-22 (time will be set to 00:00:00) + * 16:34:22 (date will be set to today) + * 16:34 (date will be set to today, seconds to 0) + * now + * yesterday (time is set to 00:00:00) + * today (time is set to 00:00:00) + * tomorrow (time is set to 00:00:00) + * +5min + * -5days + * @2147483647 (seconds since epoch) + * + */ + + assert(t); + assert(usec); + + x = time(NULL); + assert_se(localtime_r(&x, &tm)); + tm.tm_isdst = -1; + + if (streq(t, "now")) + goto finish; + + else if (streq(t, "today")) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (streq(t, "yesterday")) { + tm.tm_mday --; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (streq(t, "tomorrow")) { + tm.tm_mday ++; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + + } else if (t[0] == '+') { + r = parse_sec(t+1, &plus); + if (r < 0) + return r; + + goto finish; + + } else if (t[0] == '-') { + r = parse_sec(t+1, &minus); + if (r < 0) + return r; + + goto finish; + + } else if (t[0] == '@') + return parse_sec(t + 1, usec); + + else if (endswith(t, " ago")) { + _cleanup_free_ char *z = strndup(t, strlen(t) - 4); + + if (!z) + return -ENOMEM; + + r = parse_sec(z, &minus); + if (r < 0) + return r; + + goto finish; + } else if (endswith(t, " left")) { + _cleanup_free_ char *z = strndup(t, strlen(t) - 4); + + if (!z) + return -ENOMEM; + + r = parse_sec(z, &plus); + if (r < 0) + return r; + + goto finish; + } + + for (i = 0; i < ELEMENTSOF(day_nr); i++) { + size_t skip; + + if (!startswith_no_case(t, day_nr[i].name)) + continue; + + skip = strlen(day_nr[i].name); + if (t[skip] != ' ') + continue; + + weekday = day_nr[i].nr; + t += skip + 1; + break; + } + + copy = tm; + k = strptime(t, "%y-%m-%d %H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d %H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%Y-%m-%d", &tm); + if (k && *k == 0) { + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + goto finish; + } + + tm = copy; + k = strptime(t, "%H:%M:%S", &tm); + if (k && *k == 0) + goto finish; + + tm = copy; + k = strptime(t, "%H:%M", &tm); + if (k && *k == 0) { + tm.tm_sec = 0; + goto finish; + } + + return -EINVAL; + +finish: + x = mktime(&tm); + if (x == (time_t) -1) + return -EINVAL; + + if (weekday >= 0 && tm.tm_wday != weekday) + return -EINVAL; + + ret = (usec_t) x * USEC_PER_SEC; + + ret += plus; + if (ret > minus) + ret -= minus; + else + ret = 0; + + *usec = ret; + + return 0; +} + +int parse_sec(const char *t, usec_t *usec) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "seconds", USEC_PER_SEC }, + { "second", USEC_PER_SEC }, + { "sec", USEC_PER_SEC }, + { "s", USEC_PER_SEC }, + { "minutes", USEC_PER_MINUTE }, + { "minute", USEC_PER_MINUTE }, + { "min", USEC_PER_MINUTE }, + { "months", USEC_PER_MONTH }, + { "month", USEC_PER_MONTH }, + { "msec", USEC_PER_MSEC }, + { "ms", USEC_PER_MSEC }, + { "m", USEC_PER_MINUTE }, + { "hours", USEC_PER_HOUR }, + { "hour", USEC_PER_HOUR }, + { "hr", USEC_PER_HOUR }, + { "h", USEC_PER_HOUR }, + { "days", USEC_PER_DAY }, + { "day", USEC_PER_DAY }, + { "d", USEC_PER_DAY }, + { "weeks", USEC_PER_WEEK }, + { "week", USEC_PER_WEEK }, + { "w", USEC_PER_WEEK }, + { "years", USEC_PER_YEAR }, + { "year", USEC_PER_YEAR }, + { "y", USEC_PER_YEAR }, + { "usec", 1ULL }, + { "us", 1ULL }, + { "", USEC_PER_SEC }, /* default is sec */ + }; + + const char *p, *s; + usec_t r = 0; + bool something = false; + + assert(t); + assert(usec); + + p = t; + + p += strspn(p, WHITESPACE); + s = startswith(p, "infinity"); + if (s) { + s += strspn(s, WHITESPACE); + if (*s != 0) + return -EINVAL; + + *usec = USEC_INFINITY; + return 0; + } + + for (;;) { + long long l, z = 0; + char *e; + unsigned i, n = 0; + + p += strspn(p, WHITESPACE); + + if (*p == 0) { + if (!something) + return -EINVAL; + + break; + } + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno > 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (*e == '.') { + char *b = e + 1; + + errno = 0; + z = strtoll(b, &e, 10); + if (errno > 0) + return -errno; + + if (z < 0) + return -ERANGE; + + if (e == b) + return -EINVAL; + + n = e - b; + + } else if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + usec_t k = (usec_t) z * table[i].usec; + + for (; n > 0; n--) + k /= 10; + + r += (usec_t) l * table[i].usec + k; + p = e + strlen(table[i].suffix); + + something = true; + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } + + *usec = r; + + return 0; +} + +int parse_nsec(const char *t, nsec_t *nsec) { + static const struct { + const char *suffix; + nsec_t nsec; + } table[] = { + { "seconds", NSEC_PER_SEC }, + { "second", NSEC_PER_SEC }, + { "sec", NSEC_PER_SEC }, + { "s", NSEC_PER_SEC }, + { "minutes", NSEC_PER_MINUTE }, + { "minute", NSEC_PER_MINUTE }, + { "min", NSEC_PER_MINUTE }, + { "months", NSEC_PER_MONTH }, + { "month", NSEC_PER_MONTH }, + { "msec", NSEC_PER_MSEC }, + { "ms", NSEC_PER_MSEC }, + { "m", NSEC_PER_MINUTE }, + { "hours", NSEC_PER_HOUR }, + { "hour", NSEC_PER_HOUR }, + { "hr", NSEC_PER_HOUR }, + { "h", NSEC_PER_HOUR }, + { "days", NSEC_PER_DAY }, + { "day", NSEC_PER_DAY }, + { "d", NSEC_PER_DAY }, + { "weeks", NSEC_PER_WEEK }, + { "week", NSEC_PER_WEEK }, + { "w", NSEC_PER_WEEK }, + { "years", NSEC_PER_YEAR }, + { "year", NSEC_PER_YEAR }, + { "y", NSEC_PER_YEAR }, + { "usec", NSEC_PER_USEC }, + { "us", NSEC_PER_USEC }, + { "nsec", 1ULL }, + { "ns", 1ULL }, + { "", 1ULL }, /* default is nsec */ + }; + + const char *p, *s; + nsec_t r = 0; + bool something = false; + + assert(t); + assert(nsec); + + p = t; + + p += strspn(p, WHITESPACE); + s = startswith(p, "infinity"); + if (s) { + s += strspn(s, WHITESPACE); + if (!*s != 0) + return -EINVAL; + + *nsec = NSEC_INFINITY; + return 0; + } + + for (;;) { + long long l, z = 0; + char *e; + unsigned i, n = 0; + + p += strspn(p, WHITESPACE); + + if (*p == 0) { + if (!something) + return -EINVAL; + + break; + } + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno > 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (*e == '.') { + char *b = e + 1; + + errno = 0; + z = strtoll(b, &e, 10); + if (errno > 0) + return -errno; + + if (z < 0) + return -ERANGE; + + if (e == b) + return -EINVAL; + + n = e - b; + + } else if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + nsec_t k = (nsec_t) z * table[i].nsec; + + for (; n > 0; n--) + k /= 10; + + r += (nsec_t) l * table[i].nsec + k; + p = e + strlen(table[i].suffix); + + something = true; + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } + + *nsec = r; + + return 0; +} + +bool ntp_synced(void) { + struct timex txc = {}; + + if (adjtimex(&txc) < 0) + return false; + + if (txc.status & STA_UNSYNC) + return false; + + return true; +} + +int get_timezones(char ***ret) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_strv_free_ char **zones = NULL; + size_t n_zones = 0, n_allocated = 0; + + assert(ret); + + zones = strv_new("UTC", NULL); + if (!zones) + return -ENOMEM; + + n_allocated = 2; + n_zones = 1; + + f = fopen("/usr/share/zoneinfo/zone.tab", "re"); + if (f) { + char l[LINE_MAX]; + + FOREACH_LINE(l, f, return -errno) { + char *p, *w; + size_t k; + + p = strstrip(l); + + if (isempty(p) || *p == '#') + continue; + + /* Skip over country code */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Skip over coordinates */ + p += strcspn(p, WHITESPACE); + p += strspn(p, WHITESPACE); + + /* Found timezone name */ + k = strcspn(p, WHITESPACE); + if (k <= 0) + continue; + + w = strndup(p, k); + if (!w) + return -ENOMEM; + + if (!GREEDY_REALLOC(zones, n_allocated, n_zones + 2)) { + free(w); + return -ENOMEM; + } + + zones[n_zones++] = w; + zones[n_zones] = NULL; + } + + strv_sort(zones); + + } else if (errno != ENOENT) + return -errno; + + *ret = zones; + zones = NULL; + + return 0; +} + +bool timezone_is_valid(const char *name) { + bool slash = false; + const char *p, *t; + struct stat st; + + if (!name || *name == 0 || *name == '/') + return false; + + for (p = name; *p; p++) { + if (!(*p >= '0' && *p <= '9') && + !(*p >= 'a' && *p <= 'z') && + !(*p >= 'A' && *p <= 'Z') && + !(*p == '-' || *p == '_' || *p == '+' || *p == '/')) + return false; + + if (*p == '/') { + + if (slash) + return false; + + slash = true; + } else + slash = false; + } + + if (slash) + return false; + + t = strappenda("/usr/share/zoneinfo/", name); + if (stat(t, &st) < 0) + return false; + + if (!S_ISREG(st.st_mode)) + return false; + + return true; +} +#endif + +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; + } + + return clock; +} + diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/time-util.h b/src/dhcp-manager/systemd-dhcp/src/shared/time-util.h new file mode 100644 index 00000000..578a0c1c --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/time-util.h @@ -0,0 +1,111 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include +#include + +typedef uint64_t usec_t; +typedef uint64_t nsec_t; + +#include "nm-sd-adapt.h" + +#define NSEC_FMT "%" PRIu64 +#define USEC_FMT "%" PRIu64 + +#include "macro.h" + +typedef struct dual_timestamp { + usec_t realtime; + usec_t monotonic; +} dual_timestamp; + +#define USEC_INFINITY ((usec_t) -1) +#define NSEC_INFINITY ((nsec_t) -1) + +#define MSEC_PER_SEC 1000ULL +#define USEC_PER_SEC ((usec_t) 1000000ULL) +#define USEC_PER_MSEC ((usec_t) 1000ULL) +#define NSEC_PER_SEC ((nsec_t) 1000000000ULL) +#define NSEC_PER_MSEC ((nsec_t) 1000000ULL) +#define NSEC_PER_USEC ((nsec_t) 1000ULL) + +#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC)) +#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC)) +#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE)) +#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE)) +#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR)) +#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR)) +#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY)) +#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY)) +#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC)) +#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC)) +#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC)) +#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC)) + +#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */ +#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */ +#define FORMAT_TIMESTAMP_RELATIVE_MAX 256 +#define FORMAT_TIMESPAN_MAX 64 + +#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) + +#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0, 0 }) + +usec_t now(clockid_t clock); + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts); +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u); + +static inline bool dual_timestamp_is_set(dual_timestamp *ts) { + return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || + (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY)); +} + +usec_t timespec_load(const struct timespec *ts) _pure_; +struct timespec *timespec_store(struct timespec *ts, usec_t u); + +usec_t timeval_load(const struct timeval *tv) _pure_; +struct timeval *timeval_store(struct timeval *tv, usec_t u); + +char *format_timestamp(char *buf, size_t l, usec_t t); +char *format_timestamp_utc(char *buf, size_t l, usec_t t); +char *format_timestamp_us(char *buf, size_t l, usec_t t); +char *format_timestamp_us_utc(char *buf, size_t l, usec_t t); +char *format_timestamp_relative(char *buf, size_t l, usec_t t); +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t); +void dual_timestamp_deserialize(const char *value, dual_timestamp *t); + +int parse_timestamp(const char *t, usec_t *usec); + +int parse_sec(const char *t, usec_t *usec); +int parse_nsec(const char *t, nsec_t *nsec); + +bool ntp_synced(void); + +int get_timezones(char ***l); +bool timezone_is_valid(const char *name); + +clockid_t clock_boottime_or_monotonic(void); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h b/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h new file mode 100644 index 00000000..d6181dd9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#include + +static inline uint16_t unaligned_read_be16(const void *_u) { + const uint8_t *u = _u; + + return (((uint16_t) u[0]) << 8) | + ((uint16_t) u[1]); +} + +static inline uint32_t unaligned_read_be32(const void *_u) { + const uint8_t *u = _u; + + return (((uint32_t) unaligned_read_be16(u)) << 16) | + ((uint32_t) unaligned_read_be16(u + 2)); +} + +static inline uint64_t unaligned_read_be64(const void *_u) { + const uint8_t *u = _u; + + return (((uint64_t) unaligned_read_be32(u)) << 32) | + ((uint64_t) unaligned_read_be32(u + 4)); +} + +static inline void unaligned_write_be16(void *_u, uint16_t a) { + uint8_t *u = _u; + + u[0] = (uint8_t) (a >> 8); + u[1] = (uint8_t) a; +} + +static inline void unaligned_write_be32(void *_u, uint32_t a) { + uint8_t *u = _u; + + unaligned_write_be16(u, (uint16_t) (a >> 16)); + unaligned_write_be16(u + 2, (uint16_t) a); +} + +static inline void unaligned_write_be64(void *_u, uint64_t a) { + uint8_t *u = _u; + + unaligned_write_be32(u, (uint32_t) (a >> 32)); + unaligned_write_be32(u + 4, (uint32_t) a); +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c new file mode 100644 index 00000000..cfedbfcb --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c @@ -0,0 +1,314 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2008-2011 Kay Sievers + Copyright 2012 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 . +***/ + +/* Parts of this file are based on the GLIB utf8 validation functions. The + * original license text follows. */ + +/* gutf8.c - Operations on UTF-8 strings. + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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 + */ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include + +#include "utf8.h" +#include "util.h" + +static inline bool is_unicode_valid(uint32_t ch) { + + if (ch >= 0x110000) /* End of unicode space */ + return false; + if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */ + return false; + if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */ + return false; + if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */ + return false; + + return true; +} + +static bool is_unicode_control(uint32_t ch) { + + /* + 0 to ' '-1 is the C0 range. + DEL=0x7F, and DEL+1 to 0x9F is C1 range. + '\t' is in C0 range, but more or less harmless and commonly used. + */ + + return (ch < ' ' && ch != '\t' && ch != '\n') || + (0x7F <= ch && ch <= 0x9F); +} + +/* count of characters used to encode one unicode char */ +static int utf8_encoded_expected_len(const char *str) { + unsigned char c; + + assert(str); + + c = (unsigned char) str[0]; + if (c < 0x80) + return 1; + if ((c & 0xe0) == 0xc0) + return 2; + if ((c & 0xf0) == 0xe0) + return 3; + if ((c & 0xf8) == 0xf0) + return 4; + if ((c & 0xfc) == 0xf8) + return 5; + if ((c & 0xfe) == 0xfc) + return 6; + + return 0; +} + +/* decode one unicode char */ +int utf8_encoded_to_unichar(const char *str) { + int unichar, len, i; + + assert(str); + + len = utf8_encoded_expected_len(str); + + switch (len) { + case 1: + return (int)str[0]; + case 2: + unichar = str[0] & 0x1f; + break; + case 3: + unichar = (int)str[0] & 0x0f; + break; + case 4: + unichar = (int)str[0] & 0x07; + break; + case 5: + unichar = (int)str[0] & 0x03; + break; + case 6: + unichar = (int)str[0] & 0x01; + break; + default: + return -EINVAL; + } + + for (i = 1; i < len; i++) { + if (((int)str[i] & 0xc0) != 0x80) + return -EINVAL; + unichar <<= 6; + unichar |= (int)str[i] & 0x3f; + } + + return unichar; +} + +bool utf8_is_printable_newline(const char* str, size_t length, bool newline) { + const uint8_t *p; + + assert(str); + + for (p = (const uint8_t*) str; length;) { + int encoded_len, val; + + encoded_len = utf8_encoded_valid_unichar((const char *) p); + if (encoded_len < 0 || + (size_t) encoded_len > length) + return false; + + val = utf8_encoded_to_unichar((const char*) p); + if (val < 0 || + is_unicode_control(val) || + (!newline && val == '\n')) + return false; + + length -= encoded_len; + p += encoded_len; + } + + return true; +} + +const char *utf8_is_valid(const char *str) { + const uint8_t *p; + + assert(str); + + for (p = (const uint8_t*) str; *p; ) { + int len; + + len = utf8_encoded_valid_unichar((const char *)p); + if (len < 0) + return NULL; + + p += len; + } + + return str; +} + +char *utf8_escape_invalid(const char *str) { + char *p, *s; + + assert(str); + + p = s = malloc(strlen(str) * 4 + 1); + if (!p) + return NULL; + + while (*str) { + int len; + + len = utf8_encoded_valid_unichar(str); + if (len > 0) { + s = mempcpy(s, str, len); + str += len; + } else { + s = mempcpy(s, UTF8_REPLACEMENT_CHARACTER, strlen(UTF8_REPLACEMENT_CHARACTER)); + str += 1; + } + } + + *s = '\0'; + + return p; +} + +char *ascii_is_valid(const char *str) { + const char *p; + + assert(str); + + for (p = str; *p; p++) + if ((unsigned char) *p >= 128) + return NULL; + + return (char*) str; +} + +char *utf16_to_utf8(const void *s, size_t length) { + char *r; + const uint8_t *f; + uint8_t *t; + + r = new(char, (length*3+1)/2 + 1); + if (!r) + return NULL; + + t = (uint8_t*) r; + + for (f = s; f < (const uint8_t*) s + length; f += 2) { + uint16_t c; + + c = (f[1] << 8) | f[0]; + + if (c == 0) { + *t = 0; + return r; + } else if (c < 0x80) { + *(t++) = (uint8_t) c; + } else if (c < 0x800) { + *(t++) = (uint8_t) (0xc0 | (c >> 6)); + *(t++) = (uint8_t) (0x80 | (c & 0x3f)); + } else { + *(t++) = (uint8_t) (0xe0 | (c >> 12)); + *(t++) = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); + *(t++) = (uint8_t) (0x80 | (c & 0x3f)); + } + } + + *t = 0; + + return r; +} + +/* expected size used to encode one unicode char */ +static int utf8_unichar_to_encoded_len(int unichar) { + + if (unichar < 0x80) + return 1; + if (unichar < 0x800) + return 2; + if (unichar < 0x10000) + return 3; + if (unichar < 0x200000) + return 4; + if (unichar < 0x4000000) + return 5; + + return 6; +} + +/* validate one encoded unicode char and return its length */ +int utf8_encoded_valid_unichar(const char *str) { + int len, unichar, i; + + assert(str); + + len = utf8_encoded_expected_len(str); + if (len == 0) + return -EINVAL; + + /* ascii is valid */ + if (len == 1) + return 1; + + /* check if expected encoded chars are available */ + for (i = 0; i < len; i++) + if ((str[i] & 0x80) != 0x80) + return -EINVAL; + + unichar = utf8_encoded_to_unichar(str); + + /* check if encoded length matches encoded value */ + if (utf8_unichar_to_encoded_len(unichar) != len) + return -EINVAL; + + /* check if value has valid range */ + if (!is_unicode_valid(unichar)) + return -EINVAL; + + return len; +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/utf8.h b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.h new file mode 100644 index 00000000..c0879959 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.h @@ -0,0 +1,42 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2012 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 . +***/ + +#include + +#include "macro.h" + +#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd" + +const char *utf8_is_valid(const char *s) _pure_; +char *ascii_is_valid(const char *s) _pure_; +char *utf8_escape_invalid(const char *s); + +bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_; +_pure_ static inline bool utf8_is_printable(const char* str, size_t length) { + return utf8_is_printable_newline(str, length, true); +} + +char *utf16_to_utf8(const void *s, size_t length); + +int utf8_encoded_valid_unichar(const char *str); +int utf8_encoded_to_unichar(const char *str); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/util.c b/src/dhcp-manager/systemd-dhcp/src/shared/util.c new file mode 100644 index 00000000..05d4eb75 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/util.c @@ -0,0 +1,7350 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + 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 . +***/ + +#include "config.h" + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef basename + +#ifdef HAVE_SYS_AUXV_H +#include +#endif + +#include "macro.h" +#include "util.h" +#if 0 /* NM_IGNORED */ +#include "ioprio.h" +#include "missing.h" +#include "log.h" +#include "strv.h" +#include "label.h" +#include "mkdir.h" +#include "path-util.h" +#include "exit-status.h" +#include "hashmap.h" +#include "env-util.h" +#include "fileio.h" +#include "device-nodes.h" +#include "utf8.h" +#include "gunicode.h" +#include "virt.h" +#include "def.h" +#endif + +#if 0 /* NM_IGNORED */ +int saved_argc = 0; +char **saved_argv = NULL; + +static volatile unsigned cached_columns = 0; +static volatile unsigned cached_lines = 0; + +size_t page_size(void) { + static thread_local size_t pgsz = 0; + long r; + + if (_likely_(pgsz > 0)) + return pgsz; + + r = sysconf(_SC_PAGESIZE); + assert(r > 0); + + pgsz = (size_t) r; + return pgsz; +} +#endif + +bool streq_ptr(const char *a, const char *b) { + + /* Like streq(), but tries to make sense of NULL pointers */ + + if (a && b) + return streq(a, b); + + if (!a && !b) + return true; + + return false; +} + +char* endswith(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return (char*) s + sl; + + if (sl < pl) + return NULL; + + if (memcmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return (char*) s + sl - pl; +} + +char* first_word(const char *s, const char *word) { + size_t sl, wl; + const char *p; + + assert(s); + assert(word); + + /* Checks if the string starts with the specified word, either + * followed by NUL or by whitespace. Returns a pointer to the + * NUL or the first character after the whitespace. */ + + sl = strlen(s); + wl = strlen(word); + + if (sl < wl) + return NULL; + + if (wl == 0) + return (char*) s; + + if (memcmp(s, word, wl) != 0) + return NULL; + + p = s + wl; + if (*p == 0) + return (char*) p; + + if (!strchr(WHITESPACE, *p)) + return NULL; + + p += strspn(p, WHITESPACE); + return (char*) p; +} + +int close_nointr(int fd) { + assert(fd >= 0); + + if (close(fd) >= 0) + return 0; + + /* + * Just ignore EINTR; a retry loop is the wrong thing to do on + * Linux. + * + * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html + * https://bugzilla.gnome.org/show_bug.cgi?id=682819 + * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR + * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain + */ + if (errno == EINTR) + return 0; + + return -errno; +} + +int safe_close(int fd) { + + /* + * Like close_nointr() but cannot fail. Guarantees errno is + * unchanged. Is a NOP with negative fds passed, and returns + * -1, so that it can be used in this syntax: + * + * fd = safe_close(fd); + */ + + if (fd >= 0) { + PROTECT_ERRNO; + + /* The kernel might return pretty much any error code + * via close(), but the fd will be closed anyway. The + * only condition we want to check for here is whether + * the fd was invalid at all... */ + + assert_se(close_nointr(fd) != -EBADF); + } + + return -1; +} + +#if 0 /* NM_IGNORED */ +void close_many(const int fds[], unsigned n_fd) { + unsigned i; + + assert(fds || n_fd <= 0); + + for (i = 0; i < n_fd; i++) + safe_close(fds[i]); +} + +int unlink_noerrno(const char *path) { + PROTECT_ERRNO; + int r; + + r = unlink(path); + if (r < 0) + return -errno; + + return 0; +} + +int parse_boolean(const char *v) { + assert(v); + + if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on")) + return 1; + else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off")) + return 0; + + return -EINVAL; +} + +int parse_pid(const char *s, pid_t* ret_pid) { + unsigned long ul = 0; + pid_t pid; + int r; + + assert(s); + assert(ret_pid); + + r = safe_atolu(s, &ul); + if (r < 0) + return r; + + pid = (pid_t) ul; + + if ((unsigned long) pid != ul) + return -ERANGE; + + if (pid <= 0) + return -ERANGE; + + *ret_pid = pid; + return 0; +} + +int parse_uid(const char *s, uid_t* ret_uid) { + unsigned long ul = 0; + uid_t uid; + int r; + + assert(s); + assert(ret_uid); + + r = safe_atolu(s, &ul); + if (r < 0) + return r; + + uid = (uid_t) ul; + + if ((unsigned long) uid != ul) + return -ERANGE; + + /* Some libc APIs use (uid_t) -1 as special placeholder */ + if (uid == (uid_t) 0xFFFFFFFF) + return -ENXIO; + + /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */ + if (uid == (uid_t) 0xFFFF) + return -ENXIO; + + *ret_uid = uid; + return 0; +} +#endif + +int safe_atou(const char *s, unsigned *ret_u) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret_u); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + + *ret_u = (unsigned) l; + return 0; +} + +#if 0 /* NM_IGNORED */ +int safe_atoi(const char *s, int *ret_i) { + char *x = NULL; + long l; + + assert(s); + assert(ret_i); + + errno = 0; + l = strtol(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((long) (int) l != l) + return -ERANGE; + + *ret_i = (int) l; + return 0; +} + +int safe_atou8(const char *s, uint8_t *ret) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((unsigned long) (uint8_t) l != l) + return -ERANGE; + + *ret = (uint8_t) l; + return 0; +} + +int safe_atou16(const char *s, uint16_t *ret) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((unsigned long) (uint16_t) l != l) + return -ERANGE; + + *ret = (uint16_t) l; + return 0; +} + +int safe_atoi16(const char *s, int16_t *ret) { + char *x = NULL; + long l; + + assert(s); + assert(ret); + + errno = 0; + l = strtol(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((long) (int16_t) l != l) + return -ERANGE; + + *ret = (int16_t) l; + return 0; +} + +int safe_atollu(const char *s, long long unsigned *ret_llu) { + char *x = NULL; + unsigned long long l; + + assert(s); + assert(ret_llu); + + errno = 0; + l = strtoull(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_llu = l; + return 0; +} + +int safe_atolli(const char *s, long long int *ret_lli) { + char *x = NULL; + long long l; + + assert(s); + assert(ret_lli); + + errno = 0; + l = strtoll(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_lli = l; + return 0; +} + +int safe_atod(const char *s, double *ret_d) { + char *x = NULL; + double d = 0; + + assert(s); + assert(ret_d); + + RUN_WITH_LOCALE(LC_NUMERIC_MASK, "C") { + errno = 0; + d = strtod(s, &x); + } + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_d = (double) d; + return 0; +} +#endif + +static size_t strcspn_escaped(const char *s, const char *reject) { + bool escaped = false; + size_t n; + + for (n=0; s[n]; n++) { + if (escaped) + escaped = false; + else if (s[n] == '\\') + escaped = true; + else if (strchr(reject, s[n])) + break; + } + /* if s ends in \, return index of previous char */ + return n - escaped; +} + +/* Split a string into words. */ +const char* split(const char **state, size_t *l, const char *separator, bool quoted) { + const char *current; + + current = *state; + + if (!*current) { + assert(**state == '\0'); + return NULL; + } + + current += strspn(current, separator); + if (!*current) { + *state = current; + return NULL; + } + + if (quoted && strchr("\'\"", *current)) { + char quotechars[2] = {*current, '\0'}; + + *l = strcspn_escaped(current + 1, quotechars); + if (current[*l + 1] == '\0' || + (current[*l + 2] && !strchr(separator, current[*l + 2]))) { + /* right quote missing or garbage at the end*/ + *state = current; + return NULL; + } + assert(current[*l + 1] == quotechars[0]); + *state = current++ + *l + 2; + } else if (quoted) { + *l = strcspn_escaped(current, separator); + *state = current + *l; + } else { + *l = strcspn(current, separator); + *state = current + *l; + } + + return current; +} + +#if 0 /* NM_IGNORED */ +int get_parent_of_pid(pid_t pid, pid_t *_ppid) { + int r; + _cleanup_free_ char *line = NULL; + long unsigned ppid; + const char *p; + + assert(pid >= 0); + assert(_ppid); + + if (pid == 0) { + *_ppid = getppid(); + return 0; + } + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r < 0) + return r; + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%lu ", /* ppid */ + &ppid) != 1) + return -EIO; + + if ((long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + + *_ppid = (pid_t) ppid; + + return 0; +} + +int get_starttime_of_pid(pid_t pid, unsigned long long *st) { + int r; + _cleanup_free_ char *line = NULL; + const char *p; + + assert(pid >= 0); + assert(st); + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r < 0) + return r; + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%*d " /* tty_nr */ + "%*d " /* tpgid */ + "%*u " /* flags */ + "%*u " /* minflt */ + "%*u " /* cminflt */ + "%*u " /* majflt */ + "%*u " /* cmajflt */ + "%*u " /* utime */ + "%*u " /* stime */ + "%*d " /* cutime */ + "%*d " /* cstime */ + "%*d " /* priority */ + "%*d " /* nice */ + "%*d " /* num_threads */ + "%*d " /* itrealvalue */ + "%llu " /* starttime */, + st) != 1) + return -EIO; + + return 0; +} +#endif + +int fchmod_umask(int fd, mode_t m) { + mode_t u; + int r; + + u = umask(0777); + r = fchmod(fd, m & (~u)) < 0 ? -errno : 0; + umask(u); + + return r; +} + +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + return s; +} + +#if 0 /* NM_IGNORED */ +int get_process_state(pid_t pid) { + const char *p; + char state; + int r; + _cleanup_free_ char *line = NULL; + + assert(pid >= 0); + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r < 0) + return r; + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " %c", &state) != 1) + return -EIO; + + return (unsigned char) state; +} + +int get_process_comm(pid_t pid, char **name) { + const char *p; + int r; + + assert(name); + assert(pid >= 0); + + p = procfs_file_alloca(pid, "comm"); + + r = read_one_line_file(p, name); + if (r == -ENOENT) + return -ESRCH; + + return r; +} + +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char *r = NULL, *k; + const char *p; + int c; + + assert(line); + assert(pid >= 0); + + p = procfs_file_alloca(pid, "cmdline"); + + f = fopen(p, "re"); + if (!f) + return -errno; + + if (max_length == 0) { + size_t len = 0, allocated = 0; + + while ((c = getc(f)) != EOF) { + + if (!GREEDY_REALLOC(r, allocated, len+2)) { + free(r); + return -ENOMEM; + } + + r[len++] = isprint(c) ? c : ' '; + } + + if (len > 0) + r[len-1] = 0; + + } else { + bool space = false; + size_t left; + + r = new(char, max_length); + if (!r) + return -ENOMEM; + + k = r; + left = max_length; + while ((c = getc(f)) != EOF) { + + if (isprint(c)) { + if (space) { + if (left <= 4) + break; + + *(k++) = ' '; + left--; + space = false; + } + + if (left <= 4) + break; + + *(k++) = (char) c; + left--; + } else + space = true; + } + + if (left <= 4) { + size_t n = MIN(left-1, 3U); + memcpy(k, "...", n); + k[n] = 0; + } else + *k = 0; + } + + /* Kernel threads have no argv[] */ + if (isempty(r)) { + _cleanup_free_ char *t = NULL; + int h; + + free(r); + + if (!comm_fallback) + return -ENOENT; + + h = get_process_comm(pid, &t); + if (h < 0) + return h; + + r = strjoin("[", t, "]", NULL); + if (!r) + return -ENOMEM; + } + + *line = r; + return 0; +} + +int is_kernel_thread(pid_t pid) { + const char *p; + size_t count; + char c; + bool eof; + FILE *f; + + if (pid == 0) + return 0; + + assert(pid > 0); + + p = procfs_file_alloca(pid, "cmdline"); + f = fopen(p, "re"); + if (!f) + return -errno; + + count = fread(&c, 1, 1, f); + eof = feof(f); + fclose(f); + + /* Kernel threads have an empty cmdline */ + + if (count <= 0) + return eof ? 1 : -errno; + + return 0; +} + +int get_process_capeff(pid_t pid, char **capeff) { + const char *p; + + assert(capeff); + assert(pid >= 0); + + p = procfs_file_alloca(pid, "status"); + + return get_status_field(p, "\nCapEff:", capeff); +} + +int get_process_exe(pid_t pid, char **name) { + const char *p; + char *d; + int r; + + assert(pid >= 0); + assert(name); + + p = procfs_file_alloca(pid, "exe"); + + r = readlink_malloc(p, name); + if (r < 0) + return r == -ENOENT ? -ESRCH : r; + + d = endswith(*name, " (deleted)"); + if (d) + *d = '\0'; + + return 0; +} + +static int get_process_id(pid_t pid, const char *field, uid_t *uid) { + _cleanup_fclose_ FILE *f = NULL; + char line[LINE_MAX]; + const char *p; + + assert(field); + assert(uid); + + if (pid == 0) + return getuid(); + + p = procfs_file_alloca(pid, "status"); + f = fopen(p, "re"); + if (!f) + return -errno; + + FOREACH_LINE(line, f, return -errno) { + char *l; + + l = strstrip(line); + + if (startswith(l, field)) { + l += strlen(field); + l += strspn(l, WHITESPACE); + + l[strcspn(l, WHITESPACE)] = 0; + + return parse_uid(l, uid); + } + } + + return -EIO; +} + +int get_process_uid(pid_t pid, uid_t *uid) { + return get_process_id(pid, "Uid:", uid); +} + +int get_process_gid(pid_t pid, gid_t *gid) { + assert_cc(sizeof(uid_t) == sizeof(gid_t)); + return get_process_id(pid, "Gid:", gid); +} +#endif + +char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + + if (!s) + return strndup(suffix, b); + + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; + + r = new(char, a+b+1); + if (!r) + return NULL; + + memcpy(r, s, a); + memcpy(r+a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strappend(const char *s, const char *suffix) { + return strnappend(s, suffix, suffix ? strlen(suffix) : 0); +} + +#if 0 /* NM_IGNORED */ +int readlinkat_malloc(int fd, const char *p, char **ret) { + size_t l = 100; + int r; + + assert(p); + assert(ret); + + for (;;) { + char *c; + ssize_t n; + + c = new(char, l); + if (!c) + return -ENOMEM; + + n = readlinkat(fd, p, c, l-1); + if (n < 0) { + r = -errno; + free(c); + return r; + } + + if ((size_t) n < l-1) { + c[n] = 0; + *ret = c; + return 0; + } + + free(c); + l *= 2; + } +} + +int readlink_malloc(const char *p, char **ret) { + return readlinkat_malloc(AT_FDCWD, p, ret); +} + +int readlink_value(const char *p, char **ret) { + _cleanup_free_ char *link = NULL; + char *value; + int r; + + r = readlink_malloc(p, &link); + if (r < 0) + return r; + + value = basename(link); + if (!value) + return -ENOENT; + + value = strdup(value); + if (!value) + return -ENOMEM; + + *ret = value; + + return 0; +} + +int readlink_and_make_absolute(const char *p, char **r) { + _cleanup_free_ char *target = NULL; + char *k; + int j; + + assert(p); + assert(r); + + j = readlink_malloc(p, &target); + if (j < 0) + return j; + + k = file_in_same_dir(p, target); + if (!k) + return -ENOMEM; + + *r = k; + return 0; +} + +int readlink_and_canonicalize(const char *p, char **r) { + char *t, *s; + int j; + + assert(p); + assert(r); + + j = readlink_and_make_absolute(p, &t); + if (j < 0) + return j; + + s = canonicalize_file_name(t); + if (s) { + free(t); + *r = s; + } else + *r = t; + + path_kill_slashes(*r); + + return 0; +} + +int reset_all_signal_handlers(void) { + int sig, r = 0; + + for (sig = 1; sig < _NSIG; sig++) { + struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; + + /* These two cannot be caught... */ + if (sig == SIGKILL || sig == SIGSTOP) + continue; + + /* On Linux the first two RT signals are reserved by + * glibc, and sigaction() will return EINVAL for them. */ + if ((sigaction(sig, &sa, NULL) < 0)) + if (errno != EINVAL && r == 0) + r = -errno; + } + + return r; +} + +int reset_signal_mask(void) { + sigset_t ss; + + if (sigemptyset(&ss) < 0) + return -errno; + + if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) + return -errno; + + return 0; +} +#endif + +char *strstrip(char *s) { + char *e; + + /* Drops trailing whitespace. Modifies the string in + * place. Returns pointer to first non-space character */ + + s += strspn(s, WHITESPACE); + + for (e = strchr(s, 0); e > s; e --) + if (!strchr(WHITESPACE, e[-1])) + break; + + *e = 0; + + return s; +} + +#if 0 /* NM_IGNORED */ +char *delete_chars(char *s, const char *bad) { + char *f, *t; + + /* Drops all whitespace, regardless where in the string */ + + for (f = s, t = s; *f; f++) { + if (strchr(bad, *f)) + continue; + + *(t++) = *f; + } + + *t = 0; + + return s; +} + +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *r; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + if (!(e = strrchr(path, '/'))) + return strdup(filename); + + k = strlen(filename); + if (!(r = new(char, e-path+1+k+1))) + return NULL; + + memcpy(r, path, e-path+1); + memcpy(r+(e-path)+1, filename, k+1); + + return r; +} + +int rmdir_parents(const char *path, const char *stop) { + size_t l; + int r = 0; + + assert(path); + assert(stop); + + l = strlen(path); + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + while (l > 0) { + char *t; + + /* Skip last component */ + while (l > 0 && path[l-1] != '/') + l--; + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + if (l <= 0) + break; + + if (!(t = strndup(path, l))) + return -ENOMEM; + + if (path_startswith(stop, t)) { + free(t); + return 0; + } + + r = rmdir(t); + free(t); + + if (r < 0) + if (errno != ENOENT) + return -errno; + } + + return 0; +} +#endif + +char hexchar(int x) { + static const char table[16] = "0123456789abcdef"; + + return table[x & 15]; +} + +int unhexchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -EINVAL; +} + +char *hexmem(const void *p, size_t l) { + char *r, *z; + const uint8_t *x; + + z = r = malloc(l * 2 + 1); + if (!r) + return NULL; + + for (x = p; x < (const uint8_t*) p + l; x++) { + *(z++) = hexchar(*x >> 4); + *(z++) = hexchar(*x & 15); + } + + *z = 0; + return r; +} + +void *unhexmem(const char *p, size_t l) { + uint8_t *r, *z; + const char *x; + + assert(p); + + z = r = malloc((l + 1) / 2 + 1); + if (!r) + return NULL; + + for (x = p; x < p + l; x += 2) { + int a, b; + + a = unhexchar(x[0]); + if (x+1 < p + l) + b = unhexchar(x[1]); + else + b = 0; + + *(z++) = (uint8_t) a << 4 | (uint8_t) b; + } + + *z = 0; + return r; +} + +char octchar(int x) { + return '0' + (x & 7); +} + +int unoctchar(char c) { + + if (c >= '0' && c <= '7') + return c - '0'; + + return -EINVAL; +} + +char decchar(int x) { + return '0' + (x % 10); +} + +int undecchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + return -EINVAL; +} + +char *cescape(const char *s) { + char *r, *t; + const char *f; + + assert(s); + + /* Does C style string escaping. */ + + r = new(char, strlen(s)*4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; *f; f++) + + switch (*f) { + + case '\a': + *(t++) = '\\'; + *(t++) = 'a'; + break; + case '\b': + *(t++) = '\\'; + *(t++) = 'b'; + break; + case '\f': + *(t++) = '\\'; + *(t++) = 'f'; + break; + case '\n': + *(t++) = '\\'; + *(t++) = 'n'; + break; + case '\r': + *(t++) = '\\'; + *(t++) = 'r'; + break; + case '\t': + *(t++) = '\\'; + *(t++) = 't'; + break; + case '\v': + *(t++) = '\\'; + *(t++) = 'v'; + break; + case '\\': + *(t++) = '\\'; + *(t++) = '\\'; + break; + case '"': + *(t++) = '\\'; + *(t++) = '"'; + break; + case '\'': + *(t++) = '\\'; + *(t++) = '\''; + break; + + default: + /* For special chars we prefer octal over + * hexadecimal encoding, simply because glib's + * g_strescape() does the same */ + if ((*f < ' ') || (*f >= 127)) { + *(t++) = '\\'; + *(t++) = octchar((unsigned char) *f >> 6); + *(t++) = octchar((unsigned char) *f >> 3); + *(t++) = octchar((unsigned char) *f); + } else + *(t++) = *f; + break; + } + + *t = 0; + + return r; +} + +char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) { + char *r, *t; + const char *f; + size_t pl; + + assert(s); + + /* Undoes C style string escaping, and optionally prefixes it. */ + + pl = prefix ? strlen(prefix) : 0; + + r = new(char, pl+length+1); + if (!r) + return NULL; + + if (prefix) + memcpy(r, prefix, pl); + + for (f = s, t = r + pl; f < s + length; f++) { + + if (*f != '\\') { + *(t++) = *f; + continue; + } + + f++; + + switch (*f) { + + case 'a': + *(t++) = '\a'; + break; + case 'b': + *(t++) = '\b'; + break; + case 'f': + *(t++) = '\f'; + break; + case 'n': + *(t++) = '\n'; + break; + case 'r': + *(t++) = '\r'; + break; + case 't': + *(t++) = '\t'; + break; + case 'v': + *(t++) = '\v'; + break; + case '\\': + *(t++) = '\\'; + break; + case '"': + *(t++) = '"'; + break; + case '\'': + *(t++) = '\''; + break; + + case 's': + /* This is an extension of the XDG syntax files */ + *(t++) = ' '; + break; + + case 'x': { + /* hexadecimal encoding */ + int a, b; + + a = unhexchar(f[1]); + b = unhexchar(f[2]); + + if (a < 0 || b < 0 || (a == 0 && b == 0)) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = 'x'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + + break; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + /* octal encoding */ + int a, b, c; + + a = unoctchar(f[0]); + b = unoctchar(f[1]); + c = unoctchar(f[2]); + + if (a < 0 || b < 0 || c < 0 || (a == 0 && b == 0 && c == 0)) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = f[0]; + } else { + *(t++) = (char) ((a << 6) | (b << 3) | c); + f += 2; + } + + break; + } + + case 0: + /* premature end of string.*/ + *(t++) = '\\'; + goto finish; + + default: + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = *f; + break; + } + } + +finish: + *t = 0; + return r; +} + +char *cunescape_length(const char *s, size_t length) { + return cunescape_length_with_prefix(s, length, NULL); +} + +#if 0 /* NM_IGNORED */ +char *cunescape(const char *s) { + assert(s); + + return cunescape_length(s, strlen(s)); +} + +char *xescape(const char *s, const char *bad) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and all special + * chars, in \xFF style escaping. May be reversed with + * cunescape. */ + + r = new(char, strlen(s) * 4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; *f; f++) { + + if ((*f < ' ') || (*f >= 127) || + (*f == '\\') || strchr(bad, *f)) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *ascii_strlower(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + if (*p >= 'A' && *p <= 'Z') + *p = *p - 'A' + 'a'; + + return t; +} + +_pure_ static bool ignore_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, ".swp"); +} + +bool ignore_file(const char *filename) { + assert(filename); + + if (endswith(filename, "~")) + return true; + + return ignore_file_allow_backup(filename); +} + +int fd_nonblock(int fd, bool nonblock) { + int flags, nflags; + + assert(fd >= 0); + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + return -errno; + + if (nonblock) + nflags = flags | O_NONBLOCK; + else + nflags = flags & ~O_NONBLOCK; + + if (nflags == flags) + return 0; + + if (fcntl(fd, F_SETFL, nflags) < 0) + return -errno; + + return 0; +} + +int fd_cloexec(int fd, bool cloexec) { + int flags, nflags; + + assert(fd >= 0); + + flags = fcntl(fd, F_GETFD, 0); + if (flags < 0) + return -errno; + + if (cloexec) + nflags = flags | FD_CLOEXEC; + else + nflags = flags & ~FD_CLOEXEC; + + if (nflags == flags) + return 0; + + if (fcntl(fd, F_SETFD, nflags) < 0) + return -errno; + + return 0; +} + +_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { + unsigned i; + + assert(n_fdset == 0 || fdset); + + for (i = 0; i < n_fdset; i++) + if (fdset[i] == fd) + return true; + + return false; +} + +int close_all_fds(const int except[], unsigned n_except) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r = 0; + + assert(n_except == 0 || except); + + d = opendir("/proc/self/fd"); + if (!d) { + int fd; + struct rlimit rl; + + /* When /proc isn't available (for example in chroots) + * the fallback is brute forcing through the fd + * table */ + + assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0); + for (fd = 3; fd < (int) rl.rlim_max; fd ++) { + + if (fd_in_set(fd, except, n_except)) + continue; + + if (close_nointr(fd) < 0) + if (errno != EBADF && r == 0) + r = -errno; + } + + return r; + } + + while ((de = readdir(d))) { + int fd = -1; + + if (ignore_file(de->d_name)) + continue; + + if (safe_atoi(de->d_name, &fd) < 0) + /* Let's better ignore this, just in case */ + continue; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + if (fd_in_set(fd, except, n_except)) + continue; + + if (close_nointr(fd) < 0) { + /* Valgrind has its own FD and doesn't want to have it closed */ + if (errno != EBADF && r == 0) + r = -errno; + } + } + + return r; +} +#endif + +bool chars_intersect(const char *a, const char *b) { + const char *p; + + /* Returns true if any of the chars in a are in b. */ + for (p = a; *p; p++) + if (strchr(b, *p)) + return true; + + return false; +} + +#if 0 /* NM_IGNORED */ +bool fstype_is_network(const char *fstype) { + static const char table[] = + "cifs\0" + "smbfs\0" + "sshfs\0" + "ncpfs\0" + "ncp\0" + "nfs\0" + "nfs4\0" + "gfs\0" + "gfs2\0" + "glusterfs\0"; + + const char *x; + + x = startswith(fstype, "fuse."); + if (x) + fstype = x; + + return nulstr_contains(table, fstype); +} + +int chvt(int vt) { + _cleanup_close_ int fd = -1; + + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (vt < 0) { + int tiocl[2] = { + TIOCL_GETKMSGREDIRECT, + 0 + }; + + if (ioctl(fd, TIOCLINUX, tiocl) < 0) + return -errno; + + vt = tiocl[0] <= 0 ? 1 : tiocl[0]; + } + + if (ioctl(fd, VT_ACTIVATE, vt) < 0) + return -errno; + + return 0; +} + +int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { + struct termios old_termios, new_termios; + char c, line[LINE_MAX]; + + assert(f); + assert(ret); + + if (tcgetattr(fileno(f), &old_termios) >= 0) { + new_termios = old_termios; + + new_termios.c_lflag &= ~ICANON; + new_termios.c_cc[VMIN] = 1; + new_termios.c_cc[VTIME] = 0; + + if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) { + size_t k; + + if (t != USEC_INFINITY) { + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) { + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + return -ETIMEDOUT; + } + } + + k = fread(&c, 1, 1, f); + + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + + if (k <= 0) + return -EIO; + + if (need_nl) + *need_nl = c != '\n'; + + *ret = c; + return 0; + } + } + + if (t != USEC_INFINITY) { + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) + return -ETIMEDOUT; + } + + errno = 0; + if (!fgets(line, sizeof(line), f)) + return errno ? -errno : -EIO; + + truncate_nl(line); + + if (strlen(line) != 1) + return -EBADMSG; + + if (need_nl) + *need_nl = false; + + *ret = line[0]; + return 0; +} + +int ask_char(char *ret, const char *replies, const char *text, ...) { + int r; + + assert(ret); + assert(replies); + assert(text); + + for (;;) { + va_list ap; + char c; + bool need_nl = true; + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_ON, stdout); + + va_start(ap, text); + vprintf(text, ap); + va_end(ap); + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + fflush(stdout); + + r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl); + if (r < 0) { + + if (r == -EBADMSG) { + puts("Bad input, please try again."); + continue; + } + + putchar('\n'); + return r; + } + + if (need_nl) + putchar('\n'); + + if (strchr(replies, c)) { + *ret = c; + return 0; + } + + puts("Read unexpected character, please try again."); + } +} + +int ask_string(char **ret, const char *text, ...) { + assert(ret); + assert(text); + + for (;;) { + char line[LINE_MAX]; + va_list ap; + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_ON, stdout); + + va_start(ap, text); + vprintf(text, ap); + va_end(ap); + + if (on_tty()) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + fflush(stdout); + + errno = 0; + if (!fgets(line, sizeof(line), stdin)) + return errno ? -errno : -EIO; + + if (!endswith(line, "\n")) + putchar('\n'); + else { + char *s; + + if (isempty(line)) + continue; + + truncate_nl(line); + s = strdup(line); + if (!s) + return -ENOMEM; + + *ret = s; + return 0; + } + } +} + +int reset_terminal_fd(int fd, bool switch_to_text) { + struct termios termios; + int r = 0; + + /* Set terminal to some sane defaults */ + + assert(fd >= 0); + + /* We leave locked terminal attributes untouched, so that + * Plymouth may set whatever it wants to set, and we don't + * interfere with that. */ + + /* Disable exclusive mode, just in case */ + ioctl(fd, TIOCNXCL); + + /* Switch to text mode */ + if (switch_to_text) + ioctl(fd, KDSETMODE, KD_TEXT); + + /* Enable console unicode mode */ + ioctl(fd, KDSKBMODE, K_UNICODE); + + if (tcgetattr(fd, &termios) < 0) { + r = -errno; + goto finish; + } + + /* We only reset the stuff that matters to the software. How + * hardware is set up we don't touch assuming that somebody + * else will do that for us */ + + termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC); + termios.c_iflag |= ICRNL | IMAXBEL | IUTF8; + termios.c_oflag |= ONLCR; + termios.c_cflag |= CREAD; + termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE; + + termios.c_cc[VINTR] = 03; /* ^C */ + termios.c_cc[VQUIT] = 034; /* ^\ */ + termios.c_cc[VERASE] = 0177; + termios.c_cc[VKILL] = 025; /* ^X */ + termios.c_cc[VEOF] = 04; /* ^D */ + termios.c_cc[VSTART] = 021; /* ^Q */ + termios.c_cc[VSTOP] = 023; /* ^S */ + termios.c_cc[VSUSP] = 032; /* ^Z */ + termios.c_cc[VLNEXT] = 026; /* ^V */ + termios.c_cc[VWERASE] = 027; /* ^W */ + termios.c_cc[VREPRINT] = 022; /* ^R */ + termios.c_cc[VEOL] = 0; + termios.c_cc[VEOL2] = 0; + + termios.c_cc[VTIME] = 0; + termios.c_cc[VMIN] = 1; + + if (tcsetattr(fd, TCSANOW, &termios) < 0) + r = -errno; + +finish: + /* Just in case, flush all crap out */ + tcflush(fd, TCIOFLUSH); + + return r; +} + +int reset_terminal(const char *name) { + _cleanup_close_ int fd = -1; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + return reset_terminal_fd(fd, true); +} + +int open_terminal(const char *name, int mode) { + int fd, r; + unsigned c = 0; + + /* + * If a TTY is in the process of being closed opening it might + * cause EIO. This is horribly awful, but unlikely to be + * changed in the kernel. Hence we work around this problem by + * retrying a couple of times. + * + * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 + */ + + assert(!(mode & O_CREAT)); + + for (;;) { + fd = open(name, mode, 0); + if (fd >= 0) + break; + + if (errno != EIO) + return -errno; + + /* Max 1s in total */ + if (c >= 20) + return -errno; + + usleep(50 * USEC_PER_MSEC); + c++; + } + + r = isatty(fd); + if (r < 0) { + safe_close(fd); + return -errno; + } + + if (!r) { + safe_close(fd); + return -ENOTTY; + } + + return fd; +} + +int flush_fd(int fd) { + struct pollfd pollfd = { + .fd = fd, + .events = POLLIN, + }; + + for (;;) { + char buf[LINE_MAX]; + ssize_t l; + int r; + + r = poll(&pollfd, 1, 0); + if (r < 0) { + if (errno == EINTR) + continue; + + return -errno; + + } else if (r == 0) + return 0; + + l = read(fd, buf, sizeof(buf)); + if (l < 0) { + + if (errno == EINTR) + continue; + + if (errno == EAGAIN) + return 0; + + return -errno; + } else if (l == 0) + return 0; + } +} + +int acquire_terminal( + const char *name, + bool fail, + bool force, + bool ignore_tiocstty_eperm, + usec_t timeout) { + + int fd = -1, notify = -1, r = 0, wd = -1; + usec_t ts = 0; + + assert(name); + + /* We use inotify to be notified when the tty is closed. We + * create the watch before checking if we can actually acquire + * it, so that we don't lose any event. + * + * Note: strictly speaking this actually watches for the + * device being closed, it does *not* really watch whether a + * tty loses its controlling process. However, unless some + * rogue process uses TIOCNOTTY on /dev/tty *after* closing + * its tty otherwise this will not become a problem. As long + * as the administrator makes sure not configure any service + * on the same tty as an untrusted user this should not be a + * problem. (Which he probably should not do anyway.) */ + + if (timeout != USEC_INFINITY) + ts = now(CLOCK_MONOTONIC); + + if (!fail && !force) { + notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0)); + if (notify < 0) { + r = -errno; + goto fail; + } + + wd = inotify_add_watch(notify, name, IN_CLOSE); + if (wd < 0) { + r = -errno; + goto fail; + } + } + + for (;;) { + struct sigaction sa_old, sa_new = { + .sa_handler = SIG_IGN, + .sa_flags = SA_RESTART, + }; + + if (notify >= 0) { + r = flush_fd(notify); + if (r < 0) + goto fail; + } + + /* We pass here O_NOCTTY only so that we can check the return + * value TIOCSCTTY and have a reliable way to figure out if we + * successfully became the controlling process of the tty */ + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * if we already own the tty. */ + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + + /* First, try to get the tty */ + if (ioctl(fd, TIOCSCTTY, force) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); + + /* Sometimes it makes sense to ignore TIOCSCTTY + * returning EPERM, i.e. when very likely we already + * are have this controlling terminal. */ + if (r < 0 && r == -EPERM && ignore_tiocstty_eperm) + r = 0; + + if (r < 0 && (force || fail || r != -EPERM)) { + goto fail; + } + + if (r >= 0) + break; + + assert(!fail); + assert(!force); + assert(notify >= 0); + + for (;;) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + ssize_t l; + struct inotify_event *e; + + if (timeout != USEC_INFINITY) { + usec_t n; + + n = now(CLOCK_MONOTONIC); + if (ts + timeout < n) { + r = -ETIMEDOUT; + goto fail; + } + + r = fd_wait_for_event(fd, POLLIN, ts + timeout - n); + if (r < 0) + goto fail; + + if (r == 0) { + r = -ETIMEDOUT; + goto fail; + } + } + + l = read(notify, inotify_buffer, sizeof(inotify_buffer)); + if (l < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + r = -errno; + goto fail; + } + + e = (struct inotify_event*) inotify_buffer; + + while (l > 0) { + size_t step; + + if (e->wd != wd || !(e->mask & IN_CLOSE)) { + r = -EIO; + goto fail; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) l); + + e = (struct inotify_event*) ((uint8_t*) e + step); + l -= step; + } + + break; + } + + /* We close the tty fd here since if the old session + * ended our handle will be dead. It's important that + * we do this after sleeping, so that we don't enter + * an endless loop. */ + fd = safe_close(fd); + } + + safe_close(notify); + + r = reset_terminal_fd(fd, true); + if (r < 0) + log_warning("Failed to reset terminal: %s", strerror(-r)); + + return fd; + +fail: + safe_close(fd); + safe_close(notify); + + return r; +} + +int release_terminal(void) { + static const struct sigaction sa_new = { + .sa_handler = SIG_IGN, + .sa_flags = SA_RESTART, + }; + + _cleanup_close_ int fd = -1; + struct sigaction sa_old; + int r = 0; + + fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC); + if (fd < 0) + return -errno; + + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * by our own TIOCNOTTY */ + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + + if (ioctl(fd, TIOCNOTTY) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); + + return r; +} + +int sigaction_many(const struct sigaction *sa, ...) { + va_list ap; + int r = 0, sig; + + va_start(ap, sa); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int ignore_signals(int sig, ...) { + struct sigaction sa = { + .sa_handler = SIG_IGN, + .sa_flags = SA_RESTART, + }; + va_list ap; + int r = 0; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int default_signals(int sig, ...) { + struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; + va_list ap; + int r = 0; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +void safe_close_pair(int p[]) { + assert(p); + + if (p[0] == p[1]) { + /* Special case pairs which use the same fd in both + * directions... */ + p[0] = p[1] = safe_close(p[0]); + return; + } + + p[0] = safe_close(p[0]); + p[1] = safe_close(p[1]); +} +#endif + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { + uint8_t *p = buf; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + while (nbytes > 0) { + ssize_t k; + + k = read(fd, p, nbytes); + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via read() */ + + fd_wait_for_event(fd, POLLIN, USEC_INFINITY); + continue; + } + + if (k <= 0) + return n > 0 ? n : (k < 0 ? -errno : 0); + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +#if 0 /* NM_IGNORED */ +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { + const uint8_t *p = buf; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + while (nbytes > 0) { + ssize_t k; + + k = write(fd, p, nbytes); + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + + /* We knowingly ignore any return value here, + * and expect that any error/EOF is reported + * via write() */ + + fd_wait_for_event(fd, POLLOUT, USEC_INFINITY); + continue; + } + + if (k <= 0) + return n > 0 ? n : (k < 0 ? -errno : 0); + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +int parse_size(const char *t, off_t base, off_t *size) { + + /* Soo, sometimes we want to parse IEC binary suffxies, and + * sometimes SI decimal suffixes. This function can parse + * both. Which one is the right way depends on the + * context. Wikipedia suggests that SI is customary for + * hardrware metrics and network speeds, while IEC is + * customary for most data sizes used by software and volatile + * (RAM) memory. Hence be careful which one you pick! + * + * In either case we use just K, M, G as suffix, and not Ki, + * Mi, Gi or so (as IEC would suggest). That's because that's + * frickin' ugly. But this means you really need to make sure + * to document which base you are parsing when you use this + * call. */ + + struct table { + const char *suffix; + unsigned long long factor; + }; + + static const struct table iec[] = { + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + { "B", 1 }, + { "", 1 }, + }; + + static const struct table si[] = { + { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "T", 1000ULL*1000ULL*1000ULL*1000ULL }, + { "G", 1000ULL*1000ULL*1000ULL }, + { "M", 1000ULL*1000ULL }, + { "K", 1000ULL }, + { "B", 1 }, + { "", 1 }, + }; + + const struct table *table; + const char *p; + unsigned long long r = 0; + unsigned n_entries, start_pos = 0; + + assert(t); + assert(base == 1000 || base == 1024); + assert(size); + + if (base == 1000) { + table = si; + n_entries = ELEMENTSOF(si); + } else { + table = iec; + n_entries = ELEMENTSOF(iec); + } + + p = t; + do { + long long l; + unsigned long long l2; + double frac = 0; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno > 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + if (*e == '.') { + e++; + if (*e >= '0' && *e <= '9') { + char *e2; + + /* strotoull itself would accept space/+/- */ + l2 = strtoull(e, &e2, 10); + + if (errno == ERANGE) + return -errno; + + /* Ignore failure. E.g. 10.M is valid */ + frac = l2; + for (; e < e2; e++) + frac /= 10; + } + } + + e += strspn(e, WHITESPACE); + + for (i = start_pos; i < n_entries; i++) + if (startswith(e, table[i].suffix)) { + unsigned long long tmp; + if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor) + return -ERANGE; + tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor); + if (tmp > ULLONG_MAX - r) + return -ERANGE; + + r += tmp; + if ((unsigned long long) (off_t) r != r) + return -ERANGE; + + p = e + strlen(table[i].suffix); + + start_pos = i + 1; + break; + } + + if (i >= n_entries) + return -EINVAL; + + } while (*p); + + *size = r; + + return 0; +} + +int make_stdio(int fd) { + int r, s, t; + + assert(fd >= 0); + + r = dup3(fd, STDIN_FILENO, 0); + s = dup3(fd, STDOUT_FILENO, 0); + t = dup3(fd, STDERR_FILENO, 0); + + if (fd >= 3) + safe_close(fd); + + if (r < 0 || s < 0 || t < 0) + return -errno; + + /* We rely here that the new fd has O_CLOEXEC not set */ + + return 0; +} + +int make_null_stdio(void) { + int null_fd; + + null_fd = open("/dev/null", O_RDWR|O_NOCTTY); + if (null_fd < 0) + return -errno; + + return make_stdio(null_fd); +} + +bool is_device_path(const char *path) { + + /* Returns true on paths that refer to a device, either in + * sysfs or in /dev */ + + return + path_startswith(path, "/dev/") || + path_startswith(path, "/sys/"); +} + +int dir_is_empty(const char *path) { + _cleanup_closedir_ DIR *d; + + d = opendir(path); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + + errno = 0; + de = readdir(d); + if (!de && errno != 0) + return -errno; + + if (!de) + return 1; + + if (!ignore_file(de->d_name)) + return 0; + } +} + +char* dirname_malloc(const char *path) { + char *d, *dir, *dir2; + + d = strdup(path); + if (!d) + return NULL; + dir = dirname(d); + assert(dir); + + if (dir != d) { + dir2 = strdup(dir); + free(d); + return dir2; + } + + return dir; +} +#endif + +int dev_urandom(void *p, size_t n) { +#if 0 /* NM_IGNORED */ + static int have_syscall = -1; + int r, fd; + ssize_t k; + + /* Gathers some randomness from the kernel. This call will + * never block, and will always return some data from the + * kernel, regardless if the random pool is fully initialized + * or not. It thus makes no guarantee for the quality of the + * returned entropy, but is good enough for or usual usecases + * of seeding the hash functions for hashtable */ + + /* Use the getrandom() syscall unless we know we don't have + * it, or when the requested size is too large for it. */ + if (have_syscall != 0 || (size_t) (int) n != n) { + r = getrandom(p, n, GRND_NONBLOCK); + if (r == (int) n) { + have_syscall = true; + return 0; + } + + if (r < 0) { + if (errno == ENOSYS) + /* we lack the syscall, continue with + * reading from /dev/urandom */ + have_syscall = false; + else if (errno == EAGAIN) + /* not enough entropy for now. Let's + * remember to use the syscall the + * next time, again, but also read + * from /dev/urandom for now, which + * doesn't care about the current + * amount of entropy. */ + have_syscall = true; + else + return -errno; + } else + /* too short read? */ + return -EIO; + } +#else /* NM IGNORED */ + int fd; + ssize_t k; +#endif + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return errno == ENOENT ? -ENOSYS : -errno; + + k = loop_read(fd, p, n, true); + safe_close(fd); + + if (k < 0) + return (int) k; + if ((size_t) k != n) + return -EIO; + + return 0; +} + +void initialize_srand(void) { + static bool srand_called = false; + unsigned x; +#ifdef HAVE_SYS_AUXV_H + void *auxv; +#endif + + if (srand_called) + return; + + x = 0; + +#ifdef HAVE_SYS_AUXV_H + /* The kernel provides us with a bit of entropy in auxv, so + * let's try to make use of that to seed the pseudo-random + * generator. It's better than nothing... */ + + auxv = (void*) getauxval(AT_RANDOM); + if (auxv) + x ^= *(unsigned*) auxv; +#endif + + x ^= (unsigned) now(CLOCK_REALTIME); + x ^= (unsigned) gettid(); + + srand(x); + srand_called = true; +} + +void random_bytes(void *p, size_t n) { + uint8_t *q; + int r; + + r = dev_urandom(p, n); + if (r >= 0) + return; + + /* If some idiot made /dev/urandom unavailable to us, he'll + * get a PRNG instead. */ + + initialize_srand(); + + for (q = p; q < (uint8_t*) p + n; q ++) + *q = rand(); +} + +#if 0 /* NM_IGNORED */ +void rename_process(const char name[8]) { + assert(name); + + /* This is a like a poor man's setproctitle(). It changes the + * comm field, argv[0], and also the glibc's internally used + * name of the process. For the first one a limit of 16 chars + * applies, to the second one usually one of 10 (i.e. length + * of "/sbin/init"), to the third one one of 7 (i.e. length of + * "systemd"). If you pass a longer string it will be + * truncated */ + + prctl(PR_SET_NAME, name); + + if (program_invocation_name) + strncpy(program_invocation_name, name, strlen(program_invocation_name)); + + if (saved_argc > 0) { + int i; + + if (saved_argv[0]) + strncpy(saved_argv[0], name, strlen(saved_argv[0])); + + for (i = 1; i < saved_argc; i++) { + if (!saved_argv[i]) + break; + + memzero(saved_argv[i], strlen(saved_argv[i])); + } + } +} + +void sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int sig; + + assert(ss); + + va_start(ap, ss); + while ((sig = va_arg(ap, int)) > 0) + assert_se(sigaddset(ss, sig) == 0); + va_end(ap); +} + +int sigprocmask_many(int how, ...) { + va_list ap; + sigset_t ss; + int sig; + + assert_se(sigemptyset(&ss) == 0); + + va_start(ap, how); + while ((sig = va_arg(ap, int)) > 0) + assert_se(sigaddset(&ss, sig) == 0); + va_end(ap); + + if (sigprocmask(how, &ss, NULL) < 0) + return -errno; + + return 0; +} + +char* gethostname_malloc(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + if (!isempty(u.nodename) && !streq(u.nodename, "(none)")) + return strdup(u.nodename); + + return strdup(u.sysname); +} + +bool hostname_is_set(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + return !isempty(u.nodename) && !streq(u.nodename, "(none)"); +} + +char *lookup_uid(uid_t uid) { + long bufsize; + char *name; + _cleanup_free_ char *buf = NULL; + struct passwd pwbuf, *pw = NULL; + + /* Shortcut things to avoid NSS lookups */ + if (uid == 0) + return strdup("root"); + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize <= 0) + bufsize = 4096; + + buf = malloc(bufsize); + if (!buf) + return NULL; + + if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) + return strdup(pw->pw_name); + + if (asprintf(&name, UID_FMT, uid) < 0) + return NULL; + + return name; +} + +char* getlogname_malloc(void) { + uid_t uid; + struct stat st; + + if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0) + uid = st.st_uid; + else + uid = getuid(); + + return lookup_uid(uid); +} + +char *getusername_malloc(void) { + const char *e; + + e = getenv("USER"); + if (e) + return strdup(e); + + return lookup_uid(getuid()); +} + +int getttyname_malloc(int fd, char **r) { + char path[PATH_MAX], *c; + int k; + + assert(r); + + k = ttyname_r(fd, path, sizeof(path)); + if (k > 0) + return -k; + + char_array_0(path); + + c = strdup(startswith(path, "/dev/") ? path + 5 : path); + if (!c) + return -ENOMEM; + + *r = c; + return 0; +} + +int getttyname_harder(int fd, char **r) { + int k; + char *s; + + k = getttyname_malloc(fd, &s); + if (k < 0) + return k; + + if (streq(s, "tty")) { + free(s); + return get_ctty(0, NULL, r); + } + + *r = s; + return 0; +} + +int get_ctty_devnr(pid_t pid, dev_t *d) { + int r; + _cleanup_free_ char *line = NULL; + const char *p; + unsigned long ttynr; + + assert(pid >= 0); + + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r < 0) + return r; + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%lu ", /* ttynr */ + &ttynr) != 1) + return -EIO; + + if (major(ttynr) == 0 && minor(ttynr) == 0) + return -ENOENT; + + if (d) + *d = (dev_t) ttynr; + + return 0; +} + +int get_ctty(pid_t pid, dev_t *_devnr, char **r) { + char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL; + _cleanup_free_ char *s = NULL; + const char *p; + dev_t devnr; + int k; + + assert(r); + + k = get_ctty_devnr(pid, &devnr); + if (k < 0) + return k; + + sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr)); + + k = readlink_malloc(fn, &s); + if (k < 0) { + + if (k != -ENOENT) + return k; + + /* This is an ugly hack */ + if (major(devnr) == 136) { + asprintf(&b, "pts/%u", minor(devnr)); + goto finish; + } + + /* Probably something like the ptys which have no + * symlink in /dev/char. Let's return something + * vaguely useful. */ + + b = strdup(fn + 5); + goto finish; + } + + if (startswith(s, "/dev/")) + p = s + 5; + else if (startswith(s, "../")) + p = s + 3; + else + p = s; + + b = strdup(p); + +finish: + if (!b) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; +} + +int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { + _cleanup_closedir_ DIR *d = NULL; + int ret = 0; + + assert(fd >= 0); + + /* This returns the first error we run into, but nevertheless + * tries to go on. This closes the passed fd. */ + + d = fdopendir(fd); + if (!d) { + safe_close(fd); + + return errno == ENOENT ? 0 : -errno; + } + + for (;;) { + struct dirent *de; + bool is_dir, keep_around; + struct stat st; + int r; + + errno = 0; + de = readdir(d); + if (!de) { + if (errno != 0 && ret == 0) + ret = -errno; + return ret; + } + + if (streq(de->d_name, ".") || streq(de->d_name, "..")) + continue; + + if (de->d_type == DT_UNKNOWN || + honour_sticky || + (de->d_type == DT_DIR && root_dev)) { + if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + is_dir = S_ISDIR(st.st_mode); + keep_around = + honour_sticky && + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); + } else { + is_dir = de->d_type == DT_DIR; + keep_around = false; + } + + if (is_dir) { + int subdir_fd; + + /* if root_dev is set, remove subdirectories only, if device is same as dir */ + if (root_dev && st.st_dev != root_dev->st_dev) + continue; + + subdir_fd = openat(fd, de->d_name, + O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (subdir_fd < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev); + if (r < 0 && ret == 0) + ret = r; + + if (!keep_around) + if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + + } else if (!only_dirs && !keep_around) { + + if (unlinkat(fd, de->d_name, 0) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + } + } +} + +_pure_ static int is_temporary_fs(struct statfs *s) { + assert(s); + + return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || + F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); +} + +int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { + struct statfs s; + + assert(fd >= 0); + + if (fstatfs(fd, &s) < 0) { + safe_close(fd); + return -errno; + } + + /* We refuse to clean disk file systems with this call. This + * is extra paranoia just to be sure we never ever remove + * non-state data */ + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + safe_close(fd); + return -EPERM; + } + + return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev); +} + +static int file_is_priv_sticky(const char *p) { + struct stat st; + + assert(p); + + if (lstat(p, &st) < 0) + return -errno; + + return + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); +} + +static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) { + int fd, r; + struct statfs s; + + assert(path); + + /* We refuse to clean the root file system with this + * call. This is extra paranoia to never cause a really + * seriously broken system. */ + if (path_equal(path, "/")) { + log_error("Attempted to remove entire root file system, and we can't allow that."); + return -EPERM; + } + + fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + if (fd < 0) { + + if (errno != ENOTDIR) + return -errno; + + if (!dangerous) { + if (statfs(path, &s) < 0) + return -errno; + + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + return -EPERM; + } + } + + if (delete_root && !only_dirs) + if (unlink(path) < 0 && errno != ENOENT) + return -errno; + + return 0; + } + + if (!dangerous) { + if (fstatfs(fd, &s) < 0) { + safe_close(fd); + return -errno; + } + + if (!is_temporary_fs(&s)) { + log_error("Attempted to remove disk file system, and we can't allow that."); + safe_close(fd); + return -EPERM; + } + } + + r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL); + if (delete_root) { + + if (honour_sticky && file_is_priv_sticky(path) > 0) + return r; + + if (rmdir(path) < 0 && errno != ENOENT) { + if (r == 0) + r = -errno; + } + } + + return r; +} + +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { + return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false); +} + +int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { + return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true); +} + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { + assert(path); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (mode != (mode_t) -1) + if (chmod(path, mode) < 0) + return -errno; + + if (uid != (uid_t) -1 || gid != (gid_t) -1) + if (chown(path, uid, gid) < 0) + return -errno; + + return 0; +} + +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) { + assert(fd >= 0); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (mode != (mode_t) -1) + if (fchmod(fd, mode) < 0) + return -errno; + + if (uid != (uid_t) -1 || gid != (gid_t) -1) + if (fchown(fd, uid, gid) < 0) + return -errno; + + return 0; +} + +cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + cpu_set_t *r; + unsigned n = 1024; + + /* Allocates the cpuset in the right size */ + + for (;;) { + if (!(r = CPU_ALLOC(n))) + return NULL; + + if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) { + CPU_ZERO_S(CPU_ALLOC_SIZE(n), r); + + if (ncpus) + *ncpus = n; + + return r; + } + + CPU_FREE(r); + + if (errno != EINVAL) + return NULL; + + n *= 2; + } +} + +int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) { + static const char status_indent[] = " "; /* "[" STATUS "] " */ + _cleanup_free_ char *s = NULL; + _cleanup_close_ int fd = -1; + struct iovec iovec[6] = {}; + int n = 0; + static bool prev_ephemeral; + + assert(format); + + /* This is independent of logging, as status messages are + * optional and go exclusively to the console. */ + + if (vasprintf(&s, format, ap) < 0) + return log_oom(); + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + if (ellipse) { + char *e; + size_t emax, sl; + int c; + + c = fd_columns(fd); + if (c <= 0) + c = 80; + + sl = status ? sizeof(status_indent)-1 : 0; + + emax = c - sl - 1; + if (emax < 3) + emax = 3; + + e = ellipsize(s, emax, 50); + if (e) { + free(s); + s = e; + } + } + + if (prev_ephemeral) + IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE); + prev_ephemeral = ephemeral; + + if (status) { + if (!isempty(status)) { + IOVEC_SET_STRING(iovec[n++], "["); + IOVEC_SET_STRING(iovec[n++], status); + IOVEC_SET_STRING(iovec[n++], "] "); + } else + IOVEC_SET_STRING(iovec[n++], status_indent); + } + + IOVEC_SET_STRING(iovec[n++], s); + if (!ephemeral) + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(fd, iovec, n) < 0) + return -errno; + + return 0; +} + +int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) { + va_list ap; + int r; + + assert(format); + + va_start(ap, format); + r = status_vprintf(status, ellipse, ephemeral, format, ap); + va_end(ap); + + return r; +} + +char *replace_env(const char *format, char **env) { + enum { + WORD, + CURLY, + VARIABLE + } state = WORD; + + const char *e, *word = format; + char *r = NULL, *k; + + assert(format); + + for (e = format; *e; e ++) { + + switch (state) { + + case WORD: + if (*e == '$') + state = CURLY; + break; + + case CURLY: + if (*e == '{') { + k = strnappend(r, word, e-word-1); + if (!k) + goto fail; + + free(r); + r = k; + + word = e-1; + state = VARIABLE; + + } else if (*e == '$') { + k = strnappend(r, word, e-word); + if (!k) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } else + state = WORD; + break; + + case VARIABLE: + if (*e == '}') { + const char *t; + + t = strempty(strv_env_get_n(env, word+2, e-word-2)); + + k = strappend(r, t); + if (!k) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } + break; + } + } + + k = strnappend(r, word, e-word); + if (!k) + goto fail; + + free(r); + return k; + +fail: + free(r); + return NULL; +} + +#if 0 /* NM_IGNORED */ +char **replace_env_argv(char **argv, char **env) { + char **ret, **i; + unsigned k = 0, l = 0; + + l = strv_length(argv); + + ret = new(char*, l+1); + if (!ret) + return NULL; + + STRV_FOREACH(i, argv) { + + /* If $FOO appears as single word, replace it by the split up variable */ + if ((*i)[0] == '$' && (*i)[1] != '{') { + char *e; + char **w, **m; + unsigned q; + + e = strv_env_get(env, *i+1); + if (e) { + int r; + + r = strv_split_quoted(&m, e, true); + if (r < 0) { + ret[k] = NULL; + strv_free(ret); + return NULL; + } + } else + m = NULL; + + q = strv_length(m); + l = l + q - 1; + + w = realloc(ret, sizeof(char*) * (l+1)); + if (!w) { + ret[k] = NULL; + strv_free(ret); + strv_free(m); + return NULL; + } + + ret = w; + if (m) { + memcpy(ret + k, m, q * sizeof(char*)); + free(m); + } + + k += q; + continue; + } + + /* If ${FOO} appears as part of a word, replace it by the variable as-is */ + ret[k] = replace_env(*i, env); + if (!ret[k]) { + strv_free(ret); + return NULL; + } + k++; + } + + ret[k] = NULL; + return ret; +} +#endif + +int fd_columns(int fd) { + struct winsize ws = {}; + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_col <= 0) + return -EIO; + + return ws.ws_col; +} + +unsigned columns(void) { + const char *e; + int c; + + if (_likely_(cached_columns > 0)) + return cached_columns; + + c = 0; + e = getenv("COLUMNS"); + if (e) + (void) safe_atoi(e, &c); + + if (c <= 0) + c = fd_columns(STDOUT_FILENO); + + if (c <= 0) + c = 80; + + cached_columns = c; + return c; +} + +int fd_lines(int fd) { + struct winsize ws = {}; + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_row <= 0) + return -EIO; + + return ws.ws_row; +} + +unsigned lines(void) { + const char *e; + unsigned l; + + if (_likely_(cached_lines > 0)) + return cached_lines; + + l = 0; + e = getenv("LINES"); + if (e) + (void) safe_atou(e, &l); + + if (l <= 0) + l = fd_lines(STDOUT_FILENO); + + if (l <= 0) + l = 24; + + cached_lines = l; + return cached_lines; +} + +/* intended to be used as a SIGWINCH sighandler */ +void columns_lines_cache_reset(int signum) { + cached_columns = 0; + cached_lines = 0; +} + +bool on_tty(void) { + static int cached_on_tty = -1; + + if (_unlikely_(cached_on_tty < 0)) + cached_on_tty = isatty(STDOUT_FILENO) > 0; + + return cached_on_tty; +} + +int files_same(const char *filea, const char *fileb) { + struct stat a, b; + + if (stat(filea, &a) < 0) + return -errno; + + if (stat(fileb, &b) < 0) + return -errno; + + return a.st_dev == b.st_dev && + a.st_ino == b.st_ino; +} + +int running_in_chroot(void) { + int ret; + + ret = files_same("/proc/1/root", "/"); + if (ret < 0) + return ret; + + return ret == 0; +} + +static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x; + char *r; + + assert(s); + assert(percent <= 100); + assert(new_length >= 3); + + if (old_length <= 3 || old_length <= new_length) + return strndup(s, old_length); + + r = new0(char, new_length+1); + if (!r) + return NULL; + + x = (new_length * percent) / 100; + + if (x > new_length - 3) + x = new_length - 3; + + memcpy(r, s, x); + r[x] = '.'; + r[x+1] = '.'; + r[x+2] = '.'; + memcpy(r + x + 3, + s + old_length - (new_length - x - 3), + new_length - x - 3); + + return r; +} + +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x; + char *e; + const char *i, *j; + unsigned k, len, len2; + + assert(s); + assert(percent <= 100); + assert(new_length >= 3); + + /* if no multibyte characters use ascii_ellipsize_mem for speed */ + if (ascii_is_valid(s)) + return ascii_ellipsize_mem(s, old_length, new_length, percent); + + if (old_length <= 3 || old_length <= new_length) + return strndup(s, old_length); + + x = (new_length * percent) / 100; + + if (x > new_length - 3) + x = new_length - 3; + + k = 0; + for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) { + int c; + + c = utf8_encoded_to_unichar(i); + if (c < 0) + return NULL; + k += unichar_iswide(c) ? 2 : 1; + } + + if (k > x) /* last character was wide and went over quota */ + x ++; + + for (j = s + old_length; k < new_length && j > i; ) { + int c; + + j = utf8_prev_char(j); + c = utf8_encoded_to_unichar(j); + if (c < 0) + return NULL; + k += unichar_iswide(c) ? 2 : 1; + } + assert(i <= j); + + /* we don't actually need to ellipsize */ + if (i == j) + return memdup(s, old_length + 1); + + /* make space for ellipsis */ + j = utf8_next_char(j); + + len = i - s; + len2 = s + old_length - j; + e = new(char, len + 3 + len2 + 1); + if (!e) + return NULL; + + /* + printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n", + old_length, new_length, x, len, len2, k); + */ + + memcpy(e, s, len); + e[len] = 0xe2; /* tri-dot ellipsis: … */ + e[len + 1] = 0x80; + e[len + 2] = 0xa6; + + memcpy(e + len + 3, j, len2 + 1); + + return e; +} + +char *ellipsize(const char *s, size_t length, unsigned percent) { + return ellipsize_mem(s, strlen(s), length, percent); +} + +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { + _cleanup_close_ int fd = -1; + int r; + + assert(path); + + if (parents) + mkdir_parents(path, 0755); + + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644); + if (fd < 0) + return -errno; + + if (mode > 0) { + r = fchmod(fd, mode); + if (r < 0) + return -errno; + } + + if (uid != (uid_t) -1 || gid != (gid_t) -1) { + r = fchown(fd, uid, gid); + if (r < 0) + return -errno; + } + + if (stamp != USEC_INFINITY) { + struct timespec ts[2]; + + timespec_store(&ts[0], stamp); + ts[1] = ts[0]; + r = futimens(fd, ts); + } else + r = futimens(fd, NULL); + if (r < 0) + return -errno; + + return 0; +} + +int touch(const char *path) { + return touch_file(path, false, USEC_INFINITY, (uid_t) -1, (gid_t) -1, 0); +} + +char *unquote(const char *s, const char* quotes) { + size_t l; + assert(s); + + /* This is rather stupid, simply removes the heading and + * trailing quotes if there is one. Doesn't care about + * escaping or anything. We should make this smarter one + * day...*/ + + l = strlen(s); + if (l < 2) + return strdup(s); + + if (strchr(quotes, s[0]) && s[l-1] == s[0]) + return strndup(s+1, l-2); + + return strdup(s); +} + +char *normalize_env_assignment(const char *s) { + _cleanup_free_ char *value = NULL; + const char *eq; + char *p, *name; + + eq = strchr(s, '='); + if (!eq) { + char *r, *t; + + r = strdup(s); + if (!r) + return NULL; + + t = strstrip(r); + if (t != r) + memmove(r, t, strlen(t) + 1); + + return r; + } + + name = strndupa(s, eq - s); + p = strdupa(eq + 1); + + value = unquote(strstrip(p), QUOTES); + if (!value) + return NULL; + + return strjoin(strstrip(name), "=", value, NULL); +} + +int wait_for_terminate(pid_t pid, siginfo_t *status) { + siginfo_t dummy; + + assert(pid >= 1); + + if (!status) + status = &dummy; + + for (;;) { + zero(*status); + + if (waitid(P_PID, pid, status, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + return 0; + } +} + +/* + * Return values: + * < 0 : wait_for_terminate() failed to get the state of the + * process, the process was terminated by a signal, or + * failed for an unknown reason. + * >=0 : The process terminated normally, and its exit code is + * returned. + * + * That is, success is indicated by a return value of zero, and an + * error is indicated by a non-zero value. + */ +int wait_for_terminate_and_warn(const char *name, pid_t pid) { + int r; + siginfo_t status; + + assert(name); + assert(pid > 1); + + r = wait_for_terminate(pid, &status); + if (r < 0) { + log_warning("Failed to wait for %s: %s", name, strerror(-r)); + return r; + } + + if (status.si_code == CLD_EXITED) { + if (status.si_status != 0) { + log_warning("%s failed with error code %i.", name, status.si_status); + return status.si_status; + } + + log_debug("%s succeeded.", name); + return 0; + + } else if (status.si_code == CLD_KILLED || + status.si_code == CLD_DUMPED) { + + log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status)); + return -EPROTO; + } + + log_warning("%s failed due to unknown reason.", name); + return -EPROTO; +} + +noreturn void freeze(void) { + + /* Make sure nobody waits for us on a socket anymore */ + close_all_fds(NULL, 0); + + sync(); + + for (;;) + pause(); +} + +bool null_or_empty(struct stat *st) { + assert(st); + + if (S_ISREG(st->st_mode) && st->st_size <= 0) + return true; + + if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) + return true; + + return false; +} + +int null_or_empty_path(const char *fn) { + struct stat st; + + assert(fn); + + if (stat(fn, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +int null_or_empty_fd(int fd) { + struct stat st; + + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +DIR *xopendirat(int fd, const char *name, int flags) { + int nfd; + DIR *d; + + assert(!(flags & O_CREAT)); + + nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0); + if (nfd < 0) + return NULL; + + d = fdopendir(nfd); + if (!d) { + safe_close(nfd); + return NULL; + } + + return d; +} + +int signal_from_string_try_harder(const char *s) { + int signo; + assert(s); + + signo = signal_from_string(s); + if (signo <= 0) + if (startswith(s, "SIG")) + return signal_from_string(s+3); + + return signo; +} + +static char *tag_to_udev_node(const char *tagvalue, const char *by) { + _cleanup_free_ char *t = NULL, *u = NULL; + size_t enc_len; + + u = unquote(tagvalue, "\"\'"); + if (!u) + return NULL; + + enc_len = strlen(u) * 4 + 1; + t = new(char, enc_len); + if (!t) + return NULL; + + if (encode_devnode_name(u, t, enc_len) < 0) + return NULL; + + return strjoin("/dev/disk/by-", by, "/", t, NULL); +} + +char *fstab_node_to_udev_node(const char *p) { + assert(p); + + if (startswith(p, "LABEL=")) + return tag_to_udev_node(p+6, "label"); + + if (startswith(p, "UUID=")) + return tag_to_udev_node(p+5, "uuid"); + + if (startswith(p, "PARTUUID=")) + return tag_to_udev_node(p+9, "partuuid"); + + if (startswith(p, "PARTLABEL=")) + return tag_to_udev_node(p+10, "partlabel"); + + return strdup(p); +} + +bool tty_is_vc(const char *tty) { + assert(tty); + + return vtnr_from_tty(tty) >= 0; +} + +bool tty_is_console(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return streq(tty, "console"); +} + +int vtnr_from_tty(const char *tty) { + int i, r; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + if (!startswith(tty, "tty") ) + return -EINVAL; + + if (tty[3] < '0' || tty[3] > '9') + return -EINVAL; + + r = safe_atoi(tty+3, &i); + if (r < 0) + return r; + + if (i < 0 || i > 63) + return -EINVAL; + + return i; +} + +char *resolve_dev_console(char **active) { + char *tty; + + /* Resolve where /dev/console is pointing to, if /sys is actually ours + * (i.e. not read-only-mounted which is a sign for container setups) */ + + if (path_is_read_only_fs("/sys") > 0) + return NULL; + + if (read_one_line_file("/sys/class/tty/console/active", active) < 0) + return NULL; + + /* If multiple log outputs are configured the last one is what + * /dev/console points to */ + tty = strrchr(*active, ' '); + if (tty) + tty++; + else + tty = *active; + + if (streq(tty, "tty0")) { + char *tmp; + + /* Get the active VC (e.g. tty1) */ + if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) { + free(*active); + tty = *active = tmp; + } + } + + return tty; +} + +bool tty_is_vc_resolve(const char *tty) { + _cleanup_free_ char *active = NULL; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + if (streq(tty, "console")) { + tty = resolve_dev_console(&active); + if (!tty) + return false; + } + + return tty_is_vc(tty); +} + +const char *default_term_for_tty(const char *tty) { + assert(tty); + + return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102"; +} + +bool dirent_is_file(const struct dirent *de) { + assert(de); + + if (ignore_file(de->d_name)) + return false; + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + return true; +} + +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { + assert(de); + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + if (ignore_file_allow_backup(de->d_name)) + return false; + + return endswith(de->d_name, suffix); +} + +void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) { + pid_t executor_pid; + int r; + + assert(directory); + + /* Executes all binaries in a directory in parallel and waits + * for them to finish. Optionally a timeout is applied. */ + + executor_pid = fork(); + if (executor_pid < 0) { + log_error("Failed to fork: %m"); + return; + + } else if (executor_pid == 0) { + _cleanup_hashmap_free_free_ Hashmap *pids = NULL; + _cleanup_closedir_ DIR *_d = NULL; + struct dirent *de; + + /* We fork this all off from a child process so that + * we can somewhat cleanly make use of SIGALRM to set + * a time limit */ + + reset_all_signal_handlers(); + reset_signal_mask(); + + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + + if (!d) { + d = _d = opendir(directory); + if (!d) { + if (errno == ENOENT) + _exit(EXIT_SUCCESS); + + log_error("Failed to enumerate directory %s: %m", directory); + _exit(EXIT_FAILURE); + } + } + + pids = hashmap_new(NULL); + if (!pids) { + log_oom(); + _exit(EXIT_FAILURE); + } + + FOREACH_DIRENT(de, d, break) { + _cleanup_free_ char *path = NULL; + pid_t pid; + + if (!dirent_is_file(de)) + continue; + + path = strjoin(directory, "/", de->d_name, NULL); + if (!path) { + log_oom(); + _exit(EXIT_FAILURE); + } + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + continue; + } else if (pid == 0) { + char *_argv[2]; + + assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); + + if (!argv) { + _argv[0] = path; + _argv[1] = NULL; + argv = _argv; + } else + argv[0] = path; + + execv(path, argv); + log_error("Failed to execute %s: %m", path); + _exit(EXIT_FAILURE); + } + + log_debug("Spawned %s as " PID_FMT ".", path, pid); + + r = hashmap_put(pids, UINT_TO_PTR(pid), path); + if (r < 0) { + log_oom(); + _exit(EXIT_FAILURE); + } + + path = NULL; + } + + /* Abort execution of this process after the + * timout. We simply rely on SIGALRM as default action + * terminating the process, and turn on alarm(). */ + + if (timeout != USEC_INFINITY) + alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC); + + while (!hashmap_isempty(pids)) { + _cleanup_free_ char *path = NULL; + pid_t pid; + + pid = PTR_TO_UINT(hashmap_first_key(pids)); + assert(pid > 0); + + path = hashmap_remove(pids, UINT_TO_PTR(pid)); + assert(path); + + wait_for_terminate_and_warn(path, pid); + } + + _exit(EXIT_SUCCESS); + } + + wait_for_terminate_and_warn(directory, executor_pid); +} + +int kill_and_sigcont(pid_t pid, int sig) { + int r; + + r = kill(pid, sig) < 0 ? -errno : 0; + + if (r >= 0) + kill(pid, SIGCONT); + + return r; +} + +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + +bool plymouth_running(void) { + return access("/run/plymouth/pid", F_OK) >= 0; +} + +char* strshorten(char *s, size_t l) { + assert(s); + + if (l < strlen(s)) + s[l] = 0; + + return s; +} +#endif + +static bool hostname_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_' || + c == '.'; +} + +bool hostname_is_valid(const char *s) { + const char *p; + bool dot; + + if (isempty(s)) + return false; + + for (p = s, dot = true; *p; p++) { + if (*p == '.') { + if (dot) + return false; + + dot = true; + } else { + if (!hostname_valid_char(*p)) + return false; + + dot = false; + } + } + + if (dot) + return false; + + if (p-s > HOST_NAME_MAX) + return false; + + return true; +} + +#if 0 /* NM_IGNORED */ +char* hostname_cleanup(char *s, bool lowercase) { + char *p, *d; + bool dot; + + for (p = s, d = s, dot = true; *p; p++) { + if (*p == '.') { + if (dot) + continue; + + *(d++) = '.'; + dot = true; + } else if (hostname_valid_char(*p)) { + *(d++) = lowercase ? tolower(*p) : *p; + dot = false; + } + + } + + if (dot && d > s) + d[-1] = 0; + else + *d = 0; + + strshorten(s, HOST_NAME_MAX); + + return s; +} + +bool machine_name_is_valid(const char *s) { + + if (!hostname_is_valid(s)) + return false; + + /* Machine names should be useful hostnames, but also be + * useful in unit names, hence we enforce a stricter length + * limitation. */ + + if (strlen(s) > 64) + return false; + + return true; +} + +int pipe_eof(int fd) { + struct pollfd pollfd = { + .fd = fd, + .events = POLLIN|POLLHUP, + }; + + int r; + + r = poll(&pollfd, 1, 0); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents & POLLHUP; +} +#endif + +int fd_wait_for_event(int fd, int event, usec_t t) { + + struct pollfd pollfd = { + .fd = fd, + .events = event, + }; + + struct timespec ts; + int r; + + r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents; +} + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { + FILE *f; + char *t; + int fd; + + assert(path); + assert(_f); + assert(_temp_path); + + t = tempfn_xxxxxx(path); + if (!t) + return -ENOMEM; + + fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC); + if (fd < 0) { + free(t); + return -errno; + } + + f = fdopen(fd, "we"); + if (!f) { + unlink(t); + free(t); + return -errno; + } + + *_f = f; + *_temp_path = t; + + return 0; +} + +#if 0 /* NM_IGNORED */ +int terminal_vhangup_fd(int fd) { + assert(fd >= 0); + + if (ioctl(fd, TIOCVHANGUP) < 0) + return -errno; + + return 0; +} + +int terminal_vhangup(const char *name) { + _cleanup_close_ int fd = -1; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + return terminal_vhangup_fd(fd); +} + +int vt_disallocate(const char *name) { + int fd, r; + unsigned u; + + /* Deallocate the VT if possible. If not possible + * (i.e. because it is the active one), at least clear it + * entirely (including the scrollback buffer) */ + + if (!startswith(name, "/dev/")) + return -EINVAL; + + if (!tty_is_vc(name)) { + /* So this is not a VT. I guess we cannot deallocate + * it then. But let's at least clear the screen */ + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[2J", /* clear screen */ + 10, false); + safe_close(fd); + + return 0; + } + + if (!startswith(name, "/dev/tty")) + return -EINVAL; + + r = safe_atou(name+8, &u); + if (r < 0) + return r; + + if (u <= 0) + return -EINVAL; + + /* Try to deallocate */ + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = ioctl(fd, VT_DISALLOCATE, u); + safe_close(fd); + + if (r >= 0) + return 0; + + if (errno != EBUSY) + return -errno; + + /* Couldn't deallocate, so let's clear it fully with + * scrollback */ + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */ + 10, false); + safe_close(fd); + + return 0; +} + +int symlink_atomic(const char *from, const char *to) { + _cleanup_free_ char *t = NULL; + + assert(from); + assert(to); + + t = tempfn_random(to); + if (!t) + return -ENOMEM; + + if (symlink(from, t) < 0) + return -errno; + + if (rename(t, to) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mknod_atomic(const char *path, mode_t mode, dev_t dev) { + _cleanup_free_ char *t = NULL; + + assert(path); + + t = tempfn_random(path); + if (!t) + return -ENOMEM; + + if (mknod(t, mode, dev) < 0) + return -errno; + + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mkfifo_atomic(const char *path, mode_t mode) { + _cleanup_free_ char *t = NULL; + + assert(path); + + t = tempfn_random(path); + if (!t) + return -ENOMEM; + + if (mkfifo(t, mode) < 0) + return -errno; + + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +bool display_is_local(const char *display) { + assert(display); + + return + display[0] == ':' && + display[1] >= '0' && + display[1] <= '9'; +} + +int socket_from_display(const char *display, char **path) { + size_t k; + char *f, *c; + + assert(display); + assert(path); + + if (!display_is_local(display)) + return -EINVAL; + + k = strspn(display+1, "0123456789"); + + f = new(char, strlen("/tmp/.X11-unix/X") + k + 1); + if (!f) + return -ENOMEM; + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, display+1, k); + c[k] = 0; + + *path = f; + + return 0; +} + +int get_user_creds( + const char **username, + uid_t *uid, gid_t *gid, + const char **home, + const char **shell) { + + struct passwd *p; + uid_t u; + + assert(username); + assert(*username); + + /* We enforce some special rules for uid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*username, "root") || streq(*username, "0")) { + *username = "root"; + + if (uid) + *uid = 0; + + if (gid) + *gid = 0; + + if (home) + *home = "/root"; + + if (shell) + *shell = "/bin/sh"; + + return 0; + } + + if (parse_uid(*username, &u) >= 0) { + errno = 0; + p = getpwuid(u); + + /* If there are multiple users with the same id, make + * sure to leave $USER to the configured value instead + * of the first occurrence in the database. However if + * the uid was configured by a numeric uid, then let's + * pick the real username from /etc/passwd. */ + if (p) + *username = p->pw_name; + } else { + errno = 0; + p = getpwnam(*username); + } + + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (uid) + *uid = p->pw_uid; + + if (gid) + *gid = p->pw_gid; + + if (home) + *home = p->pw_dir; + + if (shell) + *shell = p->pw_shell; + + return 0; +} + +char* uid_to_name(uid_t uid) { + struct passwd *p; + char *r; + + if (uid == 0) + return strdup("root"); + + p = getpwuid(uid); + if (p) + return strdup(p->pw_name); + + if (asprintf(&r, UID_FMT, uid) < 0) + return NULL; + + return r; +} + +char* gid_to_name(gid_t gid) { + struct group *p; + char *r; + + if (gid == 0) + return strdup("root"); + + p = getgrgid(gid); + if (p) + return strdup(p->gr_name); + + if (asprintf(&r, GID_FMT, gid) < 0) + return NULL; + + return r; +} + +int get_group_creds(const char **groupname, gid_t *gid) { + struct group *g; + gid_t id; + + assert(groupname); + + /* We enforce some special rules for gid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*groupname, "root") || streq(*groupname, "0")) { + *groupname = "root"; + + if (gid) + *gid = 0; + + return 0; + } + + if (parse_gid(*groupname, &id) >= 0) { + errno = 0; + g = getgrgid(id); + + if (g) + *groupname = g->gr_name; + } else { + errno = 0; + g = getgrnam(*groupname); + } + + if (!g) + return errno > 0 ? -errno : -ESRCH; + + if (gid) + *gid = g->gr_gid; + + return 0; +} + +int in_gid(gid_t gid) { + gid_t *gids; + int ngroups_max, r, i; + + if (getgid() == gid) + return 1; + + if (getegid() == gid) + return 1; + + ngroups_max = sysconf(_SC_NGROUPS_MAX); + assert(ngroups_max > 0); + + gids = alloca(sizeof(gid_t) * ngroups_max); + + r = getgroups(ngroups_max, gids); + if (r < 0) + return -errno; + + for (i = 0; i < r; i++) + if (gids[i] == gid) + return 1; + + return 0; +} + +int in_group(const char *name) { + int r; + gid_t gid; + + r = get_group_creds(&name, &gid); + if (r < 0) + return r; + + return in_gid(gid); +} + +int glob_exists(const char *path) { + _cleanup_globfree_ glob_t g = {}; + int k; + + assert(path); + + errno = 0; + k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + + if (k == GLOB_NOMATCH) + return 0; + else if (k == GLOB_NOSPACE) + return -ENOMEM; + else if (k == 0) + return !strv_isempty(g.gl_pathv); + else + return errno ? -errno : -EIO; +} + +int glob_extend(char ***strv, const char *path) { + _cleanup_globfree_ glob_t g = {}; + int k; + char **p; + + errno = 0; + k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + + if (k == GLOB_NOMATCH) + return -ENOENT; + else if (k == GLOB_NOSPACE) + return -ENOMEM; + else if (k != 0 || strv_isempty(g.gl_pathv)) + return errno ? -errno : -EIO; + + STRV_FOREACH(p, g.gl_pathv) { + k = strv_extend(strv, *p); + if (k < 0) + break; + } + + return k; +} + +int dirent_ensure_type(DIR *d, struct dirent *de) { + struct stat st; + + assert(d); + assert(de); + + if (de->d_type != DT_UNKNOWN) + return 0; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + return -errno; + + de->d_type = + S_ISREG(st.st_mode) ? DT_REG : + S_ISDIR(st.st_mode) ? DT_DIR : + S_ISLNK(st.st_mode) ? DT_LNK : + S_ISFIFO(st.st_mode) ? DT_FIFO : + S_ISSOCK(st.st_mode) ? DT_SOCK : + S_ISCHR(st.st_mode) ? DT_CHR : + S_ISBLK(st.st_mode) ? DT_BLK : + DT_UNKNOWN; + + return 0; +} + +int get_files_in_directory(const char *path, char ***list) { + _cleanup_closedir_ DIR *d = NULL; + size_t bufsize = 0, n = 0; + _cleanup_strv_free_ char **l = NULL; + + assert(path); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number. */ + + d = opendir(path); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + + errno = 0; + de = readdir(d); + if (!de && errno != 0) + return -errno; + if (!de) + break; + + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + if (list) { + /* one extra slot is needed for the terminating NULL */ + if (!GREEDY_REALLOC(l, bufsize, n + 2)) + return -ENOMEM; + + l[n] = strdup(de->d_name); + if (!l[n]) + return -ENOMEM; + + l[++n] = NULL; + } else + n++; + } + + if (list) { + *list = l; + l = NULL; /* avoid freeing */ + } + + return n; +} +#endif + +char *strjoin(const char *x, ...) { + va_list ap; + size_t l; + char *r, *p; + + va_start(ap, x); + + if (x) { + l = strlen(x); + + for (;;) { + const char *t; + size_t n; + + t = va_arg(ap, const char *); + if (!t) + break; + + n = strlen(t); + if (n > ((size_t) -1) - l) { + va_end(ap); + return NULL; + } + + l += n; + } + } else + l = 0; + + va_end(ap); + + r = new(char, l+1); + if (!r) + return NULL; + + if (x) { + p = stpcpy(r, x); + + va_start(ap, x); + + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + p = stpcpy(p, t); + } + + va_end(ap); + } else + r[0] = 0; + + return r; +} + +#if 0 /* NM_IGNORED */ +bool is_main_thread(void) { + static thread_local int cached = 0; + + if (_unlikely_(cached == 0)) + cached = getpid() == gettid() ? 1 : -1; + + return cached > 0; +} + +int block_get_whole_disk(dev_t d, dev_t *ret) { + char *p, *s; + int r; + unsigned n, m; + + assert(ret); + + /* If it has a queue this is good enough for us */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = d; + return 0; + } + + /* If it is a partition find the originating device */ + if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r < 0) + return -ENOENT; + + /* Get parent dev_t */ + if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + + if (r < 0) + return r; + + r = sscanf(s, "%u:%u", &m, &n); + free(s); + + if (r != 2) + return -EINVAL; + + /* Only return this if it is really good enough for us. */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = makedev(m, n); + return 0; + } + + return -ENOENT; +} + +static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_NONE] = "none", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", + [IOPRIO_CLASS_IDLE] = "idle" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX); + +static const char *const sigchld_code_table[] = { + [CLD_EXITED] = "exited", + [CLD_KILLED] = "killed", + [CLD_DUMPED] = "dumped", + [CLD_TRAPPED] = "trapped", + [CLD_STOPPED] = "stopped", + [CLD_CONTINUED] = "continued", +}; + +DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); + +static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { + [LOG_FAC(LOG_KERN)] = "kern", + [LOG_FAC(LOG_USER)] = "user", + [LOG_FAC(LOG_MAIL)] = "mail", + [LOG_FAC(LOG_DAEMON)] = "daemon", + [LOG_FAC(LOG_AUTH)] = "auth", + [LOG_FAC(LOG_SYSLOG)] = "syslog", + [LOG_FAC(LOG_LPR)] = "lpr", + [LOG_FAC(LOG_NEWS)] = "news", + [LOG_FAC(LOG_UUCP)] = "uucp", + [LOG_FAC(LOG_CRON)] = "cron", + [LOG_FAC(LOG_AUTHPRIV)] = "authpriv", + [LOG_FAC(LOG_FTP)] = "ftp", + [LOG_FAC(LOG_LOCAL0)] = "local0", + [LOG_FAC(LOG_LOCAL1)] = "local1", + [LOG_FAC(LOG_LOCAL2)] = "local2", + [LOG_FAC(LOG_LOCAL3)] = "local3", + [LOG_FAC(LOG_LOCAL4)] = "local4", + [LOG_FAC(LOG_LOCAL5)] = "local5", + [LOG_FAC(LOG_LOCAL6)] = "local6", + [LOG_FAC(LOG_LOCAL7)] = "local7" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0)); + +static const char *const log_level_table[] = { + [LOG_EMERG] = "emerg", + [LOG_ALERT] = "alert", + [LOG_CRIT] = "crit", + [LOG_ERR] = "err", + [LOG_WARNING] = "warning", + [LOG_NOTICE] = "notice", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG); + +static const char* const sched_policy_table[] = { + [SCHED_OTHER] = "other", + [SCHED_BATCH] = "batch", + [SCHED_IDLE] = "idle", + [SCHED_FIFO] = "fifo", + [SCHED_RR] = "rr" +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); + +static const char* const rlimit_table[_RLIMIT_MAX] = { + [RLIMIT_CPU] = "LimitCPU", + [RLIMIT_FSIZE] = "LimitFSIZE", + [RLIMIT_DATA] = "LimitDATA", + [RLIMIT_STACK] = "LimitSTACK", + [RLIMIT_CORE] = "LimitCORE", + [RLIMIT_RSS] = "LimitRSS", + [RLIMIT_NOFILE] = "LimitNOFILE", + [RLIMIT_AS] = "LimitAS", + [RLIMIT_NPROC] = "LimitNPROC", + [RLIMIT_MEMLOCK] = "LimitMEMLOCK", + [RLIMIT_LOCKS] = "LimitLOCKS", + [RLIMIT_SIGPENDING] = "LimitSIGPENDING", + [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE", + [RLIMIT_NICE] = "LimitNICE", + [RLIMIT_RTPRIO] = "LimitRTPRIO", + [RLIMIT_RTTIME] = "LimitRTTIME" +}; + +DEFINE_STRING_TABLE_LOOKUP(rlimit, int); + +static const char* const ip_tos_table[] = { + [IPTOS_LOWDELAY] = "low-delay", + [IPTOS_THROUGHPUT] = "throughput", + [IPTOS_RELIABILITY] = "reliability", + [IPTOS_LOWCOST] = "low-cost", +}; + +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); + +static const char *const __signal_table[] = { + [SIGHUP] = "HUP", + [SIGINT] = "INT", + [SIGQUIT] = "QUIT", + [SIGILL] = "ILL", + [SIGTRAP] = "TRAP", + [SIGABRT] = "ABRT", + [SIGBUS] = "BUS", + [SIGFPE] = "FPE", + [SIGKILL] = "KILL", + [SIGUSR1] = "USR1", + [SIGSEGV] = "SEGV", + [SIGUSR2] = "USR2", + [SIGPIPE] = "PIPE", + [SIGALRM] = "ALRM", + [SIGTERM] = "TERM", +#ifdef SIGSTKFLT + [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */ +#endif + [SIGCHLD] = "CHLD", + [SIGCONT] = "CONT", + [SIGSTOP] = "STOP", + [SIGTSTP] = "TSTP", + [SIGTTIN] = "TTIN", + [SIGTTOU] = "TTOU", + [SIGURG] = "URG", + [SIGXCPU] = "XCPU", + [SIGXFSZ] = "XFSZ", + [SIGVTALRM] = "VTALRM", + [SIGPROF] = "PROF", + [SIGWINCH] = "WINCH", + [SIGIO] = "IO", + [SIGPWR] = "PWR", + [SIGSYS] = "SYS" +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); + +const char *signal_to_string(int signo) { + static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1]; + const char *name; + + name = __signal_to_string(signo); + if (name) + return name; + + if (signo >= SIGRTMIN && signo <= SIGRTMAX) + snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN); + else + snprintf(buf, sizeof(buf), "%d", signo); + + return buf; +} + +int signal_from_string(const char *s) { + int signo; + int offset = 0; + unsigned u; + + signo = __signal_from_string(s); + if (signo > 0) + return signo; + + if (startswith(s, "RTMIN+")) { + s += 6; + offset = SIGRTMIN; + } + if (safe_atou(s, &u) >= 0) { + signo = (int) u + offset; + if (signo > 0 && signo < _NSIG) + return signo; + } + return -EINVAL; +} + +bool kexec_loaded(void) { + bool loaded = false; + char *s; + + if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) { + if (s[0] == '1') + loaded = true; + free(s); + } + return loaded; +} + +int prot_from_flags(int flags) { + + switch (flags & O_ACCMODE) { + + case O_RDONLY: + return PROT_READ; + + case O_WRONLY: + return PROT_WRITE; + + case O_RDWR: + return PROT_READ|PROT_WRITE; + + default: + return -EINVAL; + } +} + +char *format_bytes(char *buf, size_t l, off_t t) { + unsigned i; + + static const struct { + const char *suffix; + off_t factor; + } table[] = { + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + }; + + for (i = 0; i < ELEMENTSOF(table); i++) { + + if (t >= table[i].factor) { + snprintf(buf, l, + "%llu.%llu%s", + (unsigned long long) (t / table[i].factor), + (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL), + table[i].suffix); + + goto finish; + } + } + + snprintf(buf, l, "%lluB", (unsigned long long) t); + +finish: + buf[l-1] = 0; + return buf; + +} +#endif + +void* memdup(const void *p, size_t l) { + void *r; + + assert(p); + + r = malloc(l); + if (!r) + return NULL; + + memcpy(r, p, l); + return r; +} + +#if 0 /* NM_IGNORED */ +int fd_inc_sndbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) + return 0; + + /* If we have the privileges we will ignore the kernel limit. */ + + value = (int) n; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + return -errno; + + return 1; +} + +int fd_inc_rcvbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) + return 0; + + /* If we have the privileges we will ignore the kernel limit. */ + + value = (int) n; + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + return -errno; + return 1; +} + +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { + bool stdout_is_tty, stderr_is_tty; + pid_t parent_pid, agent_pid; + sigset_t ss, saved_ss; + unsigned n, i; + va_list ap; + char **l; + + assert(pid); + assert(path); + + /* Spawns a temporary TTY agent, making sure it goes away when + * we go away */ + + parent_pid = getpid(); + + /* First we temporarily block all signals, so that the new + * child has them blocked initially. This way, we can be sure + * that SIGTERMs are not lost we might send to the agent. */ + assert_se(sigfillset(&ss) >= 0); + assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0); + + agent_pid = fork(); + if (agent_pid < 0) { + assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); + return -errno; + } + + if (agent_pid != 0) { + assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0); + *pid = agent_pid; + return 0; + } + + /* In the child: + * + * Make sure the agent goes away when the parent dies */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + _exit(EXIT_FAILURE); + + /* Make sure we actually can kill the agent, if we need to, in + * case somebody invoked us from a shell script that trapped + * SIGTERM or so... */ + reset_all_signal_handlers(); + reset_signal_mask(); + + /* Check whether our parent died before we were able + * to set the death signal and unblock the signals */ + if (getppid() != parent_pid) + _exit(EXIT_SUCCESS); + + /* Don't leak fds to the agent */ + close_all_fds(except, n_except); + + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + + if (!stdout_is_tty || !stderr_is_tty) { + int fd; + + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via + * popen() or a similar call that expects to + * read EOF we actually do generate EOF and + * not delay this indefinitely by because we + * keep an unused copy of stdin around. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) { + log_error("Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stdout_is_tty) + dup2(fd, STDOUT_FILENO); + + if (!stderr_is_tty) + dup2(fd, STDERR_FILENO); + + if (fd > 2) + close(fd); + } + + /* Count arguments */ + va_start(ap, path); + for (n = 0; va_arg(ap, char*); n++) + ; + va_end(ap); + + /* Allocate strv */ + l = alloca(sizeof(char *) * (n + 1)); + + /* Fill in arguments */ + va_start(ap, path); + for (i = 0; i <= n; i++) + l[i] = va_arg(ap, char*); + va_end(ap); + + execv(path, l); + _exit(EXIT_FAILURE); +} + +int setrlimit_closest(int resource, const struct rlimit *rlim) { + struct rlimit highest, fixed; + + assert(rlim); + + if (setrlimit(resource, rlim) >= 0) + return 0; + + if (errno != EPERM) + return -errno; + + /* So we failed to set the desired setrlimit, then let's try + * to get as close as we can */ + assert_se(getrlimit(resource, &highest) == 0); + + fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max); + fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max); + + if (setrlimit(resource, &fixed) < 0) + return -errno; + + return 0; +} + +int getenv_for_pid(pid_t pid, const char *field, char **_value) { + _cleanup_fclose_ FILE *f = NULL; + char *value = NULL; + int r; + bool done = false; + size_t l; + const char *path; + + assert(pid >= 0); + assert(field); + assert(_value); + + path = procfs_file_alloca(pid, "environ"); + + f = fopen(path, "re"); + if (!f) + return -errno; + + l = strlen(field); + r = 0; + + do { + char line[LINE_MAX]; + unsigned i; + + for (i = 0; i < sizeof(line)-1; i++) { + int c; + + c = getc(f); + if (_unlikely_(c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (memcmp(line, field, l) == 0 && line[l] == '=') { + value = strdup(line + l + 1); + if (!value) + return -ENOMEM; + + r = 1; + break; + } + + } while (!done); + + *_value = value; + return r; +} + +bool is_valid_documentation_url(const char *url) { + assert(url); + + if (startswith(url, "http://") && url[7]) + return true; + + if (startswith(url, "https://") && url[8]) + return true; + + if (startswith(url, "file:") && url[5]) + return true; + + if (startswith(url, "info:") && url[5]) + return true; + + if (startswith(url, "man:") && url[4]) + return true; + + return false; +} + +bool in_initrd(void) { + static int saved = -1; + struct statfs s; + + if (saved >= 0) + return saved; + + /* We make two checks here: + * + * 1. the flag file /etc/initrd-release must exist + * 2. the root file system must be a memory file system + * + * The second check is extra paranoia, since misdetecting an + * initrd can have bad bad consequences due the initrd + * emptying when transititioning to the main systemd. + */ + + saved = access("/etc/initrd-release", F_OK) >= 0 && + statfs("/", &s) >= 0 && + is_temporary_fs(&s); + + return saved; +} + +void warn_melody(void) { + _cleanup_close_ int fd = -1; + + fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return; + + /* Yeah, this is synchronous. Kinda sucks. But well... */ + + ioctl(fd, KIOCSOUND, (int)(1193180/440)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, (int)(1193180/220)); + usleep(125*USEC_PER_MSEC); + + ioctl(fd, KIOCSOUND, 0); +} + +int make_console_stdio(void) { + int fd, r; + + /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ + + fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY); + if (fd < 0) { + log_error("Failed to acquire terminal: %s", strerror(-fd)); + return fd; + } + + r = make_stdio(fd); + if (r < 0) { + log_error("Failed to duplicate terminal fd: %s", strerror(-r)); + return r; + } + + return 0; +} + +int get_home_dir(char **_h) { + struct passwd *p; + const char *e; + char *h; + uid_t u; + + assert(_h); + + /* Take the user specified one */ + e = secure_getenv("HOME"); + if (e && path_is_absolute(e)) { + h = strdup(e); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + h = strdup("/root"); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_dir)) + return -EINVAL; + + h = strdup(p->pw_dir); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; +} + +int get_shell(char **_s) { + struct passwd *p; + const char *e; + char *s; + uid_t u; + + assert(_s); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + s = strdup(e); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + s = strdup("/bin/sh"); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + s = strdup(p->pw_shell); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; +} + +bool filename_is_safe(const char *p) { + + if (isempty(p)) + return false; + + if (strchr(p, '/')) + return false; + + if (streq(p, ".")) + return false; + + if (streq(p, "..")) + return false; + + if (strlen(p) > FILENAME_MAX) + return false; + + return true; +} + +bool string_is_safe(const char *p) { + const char *t; + + if (!p) + return false; + + for (t = p; *t; t++) { + if (*t > 0 && *t < ' ') + return false; + + if (strchr("\\\"\'\0x7f", *t)) + return false; + } + + return true; +} +#endif + +/** + * Check if a string contains control characters. If 'ok' is non-NULL + * it may be a string containing additional CCs to be considered OK. + */ +bool string_has_cc(const char *p, const char *ok) { + const char *t; + + assert(p); + + for (t = p; *t; t++) { + if (ok && strchr(ok, *t)) + continue; + + if (*t > 0 && *t < ' ') + return true; + + if (*t == 127) + return true; + } + + return false; +} + +#if 0 /* NM_IGNORED */ +bool path_is_safe(const char *p) { + + if (isempty(p)) + return false; + + if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) + return false; + + if (strlen(p) > PATH_MAX) + return false; + + /* The following two checks are not really dangerous, but hey, they still are confusing */ + if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./")) + return false; + + if (strstr(p, "//")) + return false; + + return true; +} + +/* hey glibc, APIs with callbacks without a user pointer are so useless */ +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), void *arg) { + size_t l, u, idx; + const void *p; + int comparison; + + l = 0; + u = nmemb; + while (l < u) { + idx = (l + u) / 2; + p = (void *)(((const char *) base) + (idx * size)); + comparison = compar(key, p, arg); + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return (void *)p; + } + return NULL; +} + +bool is_locale_utf8(void) { + const char *set; + static int cached_answer = -1; + + if (cached_answer >= 0) + goto out; + + if (!setlocale(LC_ALL, "")) { + cached_answer = true; + goto out; + } + + set = nl_langinfo(CODESET); + if (!set) { + cached_answer = true; + goto out; + } + + if (streq(set, "UTF-8")) { + cached_answer = true; + goto out; + } + + /* For LC_CTYPE=="C" return true, because CTYPE is effectly + * unset and everything can do to UTF-8 nowadays. */ + set = setlocale(LC_CTYPE, NULL); + if (!set) { + cached_answer = true; + goto out; + } + + /* Check result, but ignore the result if C was set + * explicitly. */ + cached_answer = + streq(set, "C") && + !getenv("LC_ALL") && + !getenv("LC_CTYPE") && + !getenv("LANG"); + +out: + return (bool) cached_answer; +} + +const char *draw_special_char(DrawSpecialChar ch) { + static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = { + + /* UTF-8 */ { + [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */ + [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */ + [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */ + [DRAW_TREE_SPACE] = " ", /* */ + [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */ + [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */ + [DRAW_ARROW] = "\342\206\222", /* → */ + [DRAW_DASH] = "\342\200\223", /* – */ + }, + + /* ASCII fallback */ { + [DRAW_TREE_VERTICAL] = "| ", + [DRAW_TREE_BRANCH] = "|-", + [DRAW_TREE_RIGHT] = "`-", + [DRAW_TREE_SPACE] = " ", + [DRAW_TRIANGULAR_BULLET] = ">", + [DRAW_BLACK_CIRCLE] = "*", + [DRAW_ARROW] = "->", + [DRAW_DASH] = "-", + } + }; + + return draw_table[!is_locale_utf8()][ch]; +} + +char *strreplace(const char *text, const char *old_string, const char *new_string) { + const char *f; + char *t, *r; + size_t l, old_len, new_len; + + assert(text); + assert(old_string); + assert(new_string); + + old_len = strlen(old_string); + new_len = strlen(new_string); + + l = strlen(text); + r = new(char, l+1); + if (!r) + return NULL; + + f = text; + t = r; + while (*f) { + char *a; + size_t d, nl; + + if (!startswith(f, old_string)) { + *(t++) = *(f++); + continue; + } + + d = t - r; + nl = l - old_len + new_len; + a = realloc(r, nl + 1); + if (!a) + goto oom; + + l = nl; + r = a; + t = r + d; + + t = stpcpy(t, new_string); + f += old_len; + } + + *t = 0; + return r; + +oom: + free(r); + return NULL; +} + +char *strip_tab_ansi(char **ibuf, size_t *_isz) { + const char *i, *begin = NULL; + enum { + STATE_OTHER, + STATE_ESCAPE, + STATE_BRACKET + } state = STATE_OTHER; + char *obuf = NULL; + size_t osz = 0, isz; + FILE *f; + + assert(ibuf); + assert(*ibuf); + + /* Strips ANSI color and replaces TABs by 8 spaces */ + + isz = _isz ? *_isz : strlen(*ibuf); + + f = open_memstream(&obuf, &osz); + if (!f) + return NULL; + + for (i = *ibuf; i < *ibuf + isz + 1; i++) { + + switch (state) { + + case STATE_OTHER: + if (i >= *ibuf + isz) /* EOT */ + break; + else if (*i == '\x1B') + state = STATE_ESCAPE; + else if (*i == '\t') + fputs(" ", f); + else + fputc(*i, f); + break; + + case STATE_ESCAPE: + if (i >= *ibuf + isz) { /* EOT */ + fputc('\x1B', f); + break; + } else if (*i == '[') { + state = STATE_BRACKET; + begin = i + 1; + } else { + fputc('\x1B', f); + fputc(*i, f); + state = STATE_OTHER; + } + + break; + + case STATE_BRACKET: + + if (i >= *ibuf + isz || /* EOT */ + (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) { + fputc('\x1B', f); + fputc('[', f); + state = STATE_OTHER; + i = begin-1; + } else if (*i == 'm') + state = STATE_OTHER; + break; + } + } + + if (ferror(f)) { + fclose(f); + free(obuf); + return NULL; + } + + fclose(f); + + free(*ibuf); + *ibuf = obuf; + + if (_isz) + *_isz = osz; + + return obuf; +} + +int on_ac_power(void) { + bool found_offline = false, found_online = false; + _cleanup_closedir_ DIR *d = NULL; + + d = opendir("/sys/class/power_supply"); + if (!d) + return -errno; + + for (;;) { + struct dirent *de; + _cleanup_close_ int fd = -1, device = -1; + char contents[6]; + ssize_t n; + + errno = 0; + de = readdir(d); + if (!de && errno != 0) + return -errno; + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (device < 0) { + if (errno == ENOENT || errno == ENOTDIR) + continue; + + return -errno; + } + + fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 6 || memcmp(contents, "Mains\n", 6)) + continue; + + safe_close(fd); + fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + if (errno == ENOENT) + continue; + + return -errno; + } + + n = read(fd, contents, sizeof(contents)); + if (n < 0) + return -errno; + + if (n != 2 || contents[1] != '\n') + return -EIO; + + if (contents[0] == '1') { + found_online = true; + break; + } else if (contents[0] == '0') + found_offline = true; + else + return -EIO; + } + + return found_online || !found_offline; +} + +static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) { + char **i; + + assert(path); + assert(mode); + assert(_f); + + if (!path_strv_resolve_uniq(search, root)) + return -ENOMEM; + + STRV_FOREACH(i, search) { + _cleanup_free_ char *p = NULL; + FILE *f; + + if (root) + p = strjoin(root, *i, "/", path, NULL); + else + p = strjoin(*i, "/", path, NULL); + if (!p) + return -ENOMEM; + + f = fopen(p, mode); + if (f) { + *_f = f; + return 0; + } + + if (errno != ENOENT) + return -errno; + } + + return -ENOENT; +} + +int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) { + _cleanup_strv_free_ char **copy = NULL; + + assert(path); + assert(mode); + assert(_f); + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + copy = strv_copy((char**) search); + if (!copy) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, root, copy, _f); +} + +int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) { + _cleanup_strv_free_ char **s = NULL; + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + s = strv_split_nulstr(search); + if (!s) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, root, s, _f); +} + +char *strextend(char **x, ...) { + va_list ap; + size_t f, l; + char *r, *p; + + assert(x); + + l = f = *x ? strlen(*x) : 0; + + va_start(ap, x); + for (;;) { + const char *t; + size_t n; + + t = va_arg(ap, const char *); + if (!t) + break; + + n = strlen(t); + if (n > ((size_t) -1) - l) { + va_end(ap); + return NULL; + } + + l += n; + } + va_end(ap); + + r = realloc(*x, l+1); + if (!r) + return NULL; + + p = r + f; + + va_start(ap, x); + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + p = stpcpy(p, t); + } + va_end(ap); + + *p = 0; + *x = r; + + return r + l; +} + +char *strrep(const char *s, unsigned n) { + size_t l; + char *r, *p; + unsigned i; + + assert(s); + + l = strlen(s); + p = r = malloc(l * n + 1); + if (!r) + return NULL; + + for (i = 0; i < n; i++) + p = stpcpy(p, s); + + *p = 0; + return r; +} +#endif + +void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) { + size_t a, newalloc; + void *q; + + assert(p); + assert(allocated); + + if (*allocated >= need) + return *p; + + newalloc = MAX(need * 2, 64u / size); + a = newalloc * size; + + /* check for overflows */ + if (a < size * need) + return NULL; + + q = realloc(*p, a); + if (!q) + return NULL; + + *p = q; + *allocated = newalloc; + return q; +} + +#if 0 /* NM_IGNORED */ +void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) { + size_t prev; + uint8_t *q; + + assert(p); + assert(allocated); + + prev = *allocated; + + q = greedy_realloc(p, allocated, need, size); + if (!q) + return NULL; + + if (*allocated > prev) + memzero(q + prev * size, (*allocated - prev) * size); + + return q; +} + +bool id128_is_valid(const char *s) { + size_t i, l; + + l = strlen(s); + if (l == 32) { + + /* Simple formatted 128bit hex string */ + + for (i = 0; i < l; i++) { + char c = s[i]; + + if (!(c >= '0' && c <= '9') && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z')) + return false; + } + + } else if (l == 36) { + + /* Formatted UUID */ + + for (i = 0; i < l; i++) { + char c = s[i]; + + if ((i == 8 || i == 13 || i == 18 || i == 23)) { + if (c != '-') + return false; + } else { + if (!(c >= '0' && c <= '9') && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z')) + return false; + } + } + + } else + return false; + + return true; +} + +int split_pair(const char *s, const char *sep, char **l, char **r) { + char *x, *a, *b; + + assert(s); + assert(sep); + assert(l); + assert(r); + + if (isempty(sep)) + return -EINVAL; + + x = strstr(s, sep); + if (!x) + return -EINVAL; + + a = strndup(s, x - s); + if (!a) + return -ENOMEM; + + b = strdup(x + strlen(sep)); + if (!b) { + free(a); + return -ENOMEM; + } + + *l = a; + *r = b; + + return 0; +} + +int shall_restore_state(void) { + _cleanup_free_ char *line = NULL; + const char *p; + int r; + + r = proc_cmdline(&line); + if (r < 0) + return r; + + r = 1; + p = line; + + for (;;) { + _cleanup_free_ char *word = NULL; + const char *e; + int k; + + k = unquote_first_word(&p, &word, true); + if (k < 0) + return k; + if (k == 0) + break; + + e = startswith(word, "systemd.restore_state="); + if (!e) + continue; + + k = parse_boolean(e); + if (k >= 0) + r = k; + } + + return r; +} + +int proc_cmdline(char **ret) { + assert(ret); + + if (detect_container(NULL) > 0) + return get_process_cmdline(1, 0, false, ret); + else + return read_one_line_file("/proc/cmdline", ret); +} + +int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) { + _cleanup_free_ char *line = NULL; + const char *p; + int r; + + assert(parse_item); + + r = proc_cmdline(&line); + if (r < 0) + return r; + + p = line; + for (;;) { + _cleanup_free_ char *word = NULL; + char *value = NULL; + + r = unquote_first_word(&p, &word, true); + if (r < 0) + return r; + if (r == 0) + break; + + /* Filter out arguments that are intended only for the + * initrd */ + if (!in_initrd() && startswith(word, "rd.")) + continue; + + value = strchr(word, '='); + if (value) + *(value++) = 0; + + r = parse_item(word, value); + if (r < 0) + return r; + } + + return 0; +} + +int container_get_leader(const char *machine, pid_t *pid) { + _cleanup_free_ char *s = NULL, *class = NULL; + const char *p; + pid_t leader; + int r; + + assert(machine); + assert(pid); + + p = strappenda("/run/systemd/machines/", machine); + r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL); + if (r == -ENOENT) + return -EHOSTDOWN; + if (r < 0) + return r; + if (!s) + return -EIO; + + if (!streq_ptr(class, "container")) + return -EIO; + + r = parse_pid(s, &leader); + if (r < 0) + return r; + if (leader <= 1) + return -EIO; + + *pid = leader; + return 0; +} + +int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd) { + _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1; + int rfd = -1; + + assert(pid >= 0); + + if (mntns_fd) { + const char *mntns; + + mntns = procfs_file_alloca(pid, "ns/mnt"); + mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (mntnsfd < 0) + return -errno; + } + + if (pidns_fd) { + const char *pidns; + + pidns = procfs_file_alloca(pid, "ns/pid"); + pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (pidnsfd < 0) + return -errno; + } + + if (netns_fd) { + const char *netns; + + netns = procfs_file_alloca(pid, "ns/net"); + netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (netnsfd < 0) + return -errno; + } + + if (root_fd) { + const char *root; + + root = procfs_file_alloca(pid, "root"); + rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY); + if (rfd < 0) + return -errno; + } + + if (pidns_fd) + *pidns_fd = pidnsfd; + + if (mntns_fd) + *mntns_fd = mntnsfd; + + if (netns_fd) + *netns_fd = netnsfd; + + if (root_fd) + *root_fd = rfd; + + pidnsfd = mntnsfd = netnsfd = -1; + + return 0; +} + +int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) { + + if (pidns_fd >= 0) + if (setns(pidns_fd, CLONE_NEWPID) < 0) + return -errno; + + if (mntns_fd >= 0) + if (setns(mntns_fd, CLONE_NEWNS) < 0) + return -errno; + + if (netns_fd >= 0) + if (setns(netns_fd, CLONE_NEWNET) < 0) + return -errno; + + if (root_fd >= 0) { + if (fchdir(root_fd) < 0) + return -errno; + + if (chroot(".") < 0) + return -errno; + } + + if (setresgid(0, 0, 0) < 0) + return -errno; + + if (setgroups(0, NULL) < 0) + return -errno; + + if (setresuid(0, 0, 0) < 0) + return -errno; + + return 0; +} + +bool pid_is_unwaited(pid_t pid) { + /* Checks whether a PID is still valid at all, including a zombie */ + + if (pid <= 0) + return false; + + if (kill(pid, 0) >= 0) + return true; + + return errno != ESRCH; +} + +bool pid_is_alive(pid_t pid) { + int r; + + /* Checks whether a PID is still valid and not a zombie */ + + if (pid <= 0) + return false; + + r = get_process_state(pid); + if (r == -ENOENT || r == 'Z') + return false; + + return true; +} + +int getpeercred(int fd, struct ucred *ucred) { + socklen_t n = sizeof(struct ucred); + struct ucred u; + int r; + + assert(fd >= 0); + assert(ucred); + + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n); + if (r < 0) + return -errno; + + if (n != sizeof(struct ucred)) + return -EIO; + + /* Check if the data is actually useful and not suppressed due + * to namespacing issues */ + if (u.pid <= 0) + return -ENODATA; + + *ucred = u; + return 0; +} + +int getpeersec(int fd, char **ret) { + socklen_t n = 64; + char *s; + int r; + + assert(fd >= 0); + assert(ret); + + s = new0(char, n); + if (!s) + return -ENOMEM; + + r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); + if (r < 0) { + free(s); + + if (errno != ERANGE) + return -errno; + + s = new0(char, n); + if (!s) + return -ENOMEM; + + r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); + if (r < 0) { + free(s); + return -errno; + } + } + + if (isempty(s)) { + free(s); + return -ENOTSUP; + } + + *ret = s; + return 0; +} +#endif + +/* This is much like like mkostemp() but is subject to umask(). */ +int mkostemp_safe(char *pattern, int flags) { + _cleanup_umask_ mode_t u; + int fd; + + assert(pattern); + + u = umask(077); + + fd = mkostemp(pattern, flags); + if (fd < 0) + return -errno; + + return fd; +} + +#if 0 /* NM_IGNORED */ +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, S_IRUSR|S_IWUSR); + if (fd >= 0) + return fd; +#endif + + /* Fall back to unguessable name + unlinking */ + p = strappenda(path, "/systemd-tmp-XXXXXX"); + + fd = mkostemp_safe(p, flags); + if (fd < 0) + return fd; + + unlink(p); + return fd; +} + +int fd_warn_permissions(const char *path, int fd) { + struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + if (st.st_mode & 0111) + log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path); + + if (st.st_mode & 0002) + log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path); + + if (getpid() == 1 && (st.st_mode & 0044) != 0044) + log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path); + + return 0; +} + +unsigned long personality_from_string(const char *p) { + + /* Parse a personality specifier. We introduce our own + * identifiers that indicate specific ABIs, rather than just + * hints regarding the register size, since we want to keep + * things open for multiple locally supported ABIs for the + * same register size. We try to reuse the ABI identifiers + * used by libseccomp. */ + +#if defined(__x86_64__) + + if (streq(p, "x86")) + return PER_LINUX32; + + if (streq(p, "x86-64")) + return PER_LINUX; + +#elif defined(__i386__) + + if (streq(p, "x86")) + return PER_LINUX; +#endif + + /* personality(7) documents that 0xffffffffUL is used for + * querying the current personality, hence let's use that here + * as error indicator. */ + return 0xffffffffUL; +} + +const char* personality_to_string(unsigned long p) { + +#if defined(__x86_64__) + + if (p == PER_LINUX32) + return "x86"; + + if (p == PER_LINUX) + return "x86-64"; + +#elif defined(__i386__) + + if (p == PER_LINUX) + return "x86"; +#endif + + return NULL; +} + +uint64_t physical_memory(void) { + long mem; + + /* We return this as uint64_t in case we are running as 32bit + * process on a 64bit kernel with huge amounts of memory */ + + mem = sysconf(_SC_PHYS_PAGES); + assert(mem > 0); + + return (uint64_t) mem * (uint64_t) page_size(); +} + +char* mount_test_option(const char *haystack, const char *needle) { + + struct mntent me = { + .mnt_opts = (char*) haystack + }; + + assert(needle); + + /* Like glibc's hasmntopt(), but works on a string, not a + * struct mntent */ + + if (!haystack) + return NULL; + + return hasmntopt(&me, needle); +} + +void hexdump(FILE *f, const void *p, size_t s) { + const uint8_t *b = p; + unsigned n = 0; + + assert(s == 0 || b); + + while (s > 0) { + size_t i; + + fprintf(f, "%04x ", n); + + for (i = 0; i < 16; i++) { + + if (i >= s) + fputs(" ", f); + else + fprintf(f, "%02x ", b[i]); + + if (i == 7) + fputc(' ', f); + } + + fputc(' ', f); + + for (i = 0; i < 16; i++) { + + if (i >= s) + fputc(' ', f); + else + fputc(isprint(b[i]) ? (char) b[i] : '.', f); + } + + fputc('\n', f); + + if (s < 16) + break; + + n += 16; + b += 16; + s -= 16; + } +} + +int update_reboot_param_file(const char *param) { + int r = 0; + + if (param) { + + r = write_string_file(REBOOT_PARAM_FILE, param); + if (r < 0) + log_error("Failed to write reboot param to " + REBOOT_PARAM_FILE": %s", strerror(-r)); + } else + unlink(REBOOT_PARAM_FILE); + + return r; +} + +int umount_recursive(const char *prefix, int flags) { + bool again; + int n = 0, r; + + /* Try to umount everything recursively below a + * directory. Also, take care of stacked mounts, and keep + * unmounting them until they are gone. */ + + do { + _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; + + again = false; + r = 0; + + proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); + if (!proc_self_mountinfo) + return -errno; + + for (;;) { + _cleanup_free_ char *path = NULL, *p = NULL; + int k; + + k = fscanf(proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%*s" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%*s " /* (9) file system type */ + "%*s" /* (10) mount source */ + "%*s" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &path); + if (k != 1) { + if (k == EOF) + break; + + continue; + } + + p = cunescape(path); + if (!p) + return -ENOMEM; + + if (!path_startswith(p, prefix)) + continue; + + if (umount2(p, flags) < 0) { + r = -errno; + continue; + } + + again = true; + n++; + + break; + } + + } while (again); + + return r ? r : n; +} + +int bind_remount_recursive(const char *prefix, bool ro) { + _cleanup_set_free_free_ Set *done = NULL; + _cleanup_free_ char *cleaned = NULL; + int r; + + /* Recursively remount a directory (and all its submounts) + * read-only or read-write. If the directory is already + * mounted, we reuse the mount and simply mark it + * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write + * operation). If it isn't we first make it one. Afterwards we + * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all + * submounts we can access, too. When mounts are stacked on + * the same mount point we only care for each individual + * "top-level" mount on each point, as we cannot + * influence/access the underlying mounts anyway. We do not + * have any effect on future submounts that might get + * propagated, they migt be writable. This includes future + * submounts that have been triggered via autofs. */ + + cleaned = strdup(prefix); + if (!cleaned) + return -ENOMEM; + + path_kill_slashes(cleaned); + + done = set_new(&string_hash_ops); + if (!done) + return -ENOMEM; + + for (;;) { + _cleanup_fclose_ FILE *proc_self_mountinfo = NULL; + _cleanup_set_free_free_ Set *todo = NULL; + bool top_autofs = false; + char *x; + + todo = set_new(&string_hash_ops); + if (!todo) + return -ENOMEM; + + proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); + if (!proc_self_mountinfo) + return -errno; + + for (;;) { + _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL; + int k; + + k = fscanf(proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%*s" /* (6) mount options (superblock) */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%ms " /* (9) file system type */ + "%*s" /* (10) mount source */ + "%*s" /* (11) mount options (bind mount) */ + "%*[^\n]", /* some rubbish at the end */ + &path, + &type); + if (k != 2) { + if (k == EOF) + break; + + continue; + } + + p = cunescape(path); + if (!p) + return -ENOMEM; + + /* Let's ignore autofs mounts. If they aren't + * triggered yet, we want to avoid triggering + * them, as we don't make any guarantees for + * future submounts anyway. If they are + * already triggered, then we will find + * another entry for this. */ + if (streq(type, "autofs")) { + top_autofs = top_autofs || path_equal(cleaned, p); + continue; + } + + if (path_startswith(p, cleaned) && + !set_contains(done, p)) { + + r = set_consume(todo, p); + p = NULL; + + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + } + + /* If we have no submounts to process anymore and if + * the root is either already done, or an autofs, we + * are done */ + if (set_isempty(todo) && + (top_autofs || set_contains(done, cleaned))) + return 0; + + if (!set_contains(done, cleaned) && + !set_contains(todo, cleaned)) { + /* The prefix directory itself is not yet a + * mount, make it one. */ + if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0) + return -errno; + + if (mount(NULL, prefix, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) + return -errno; + + x = strdup(cleaned); + if (!x) + return -ENOMEM; + + r = set_consume(done, x); + if (r < 0) + return r; + } + + while ((x = set_steal_first(todo))) { + + r = set_consume(done, x); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + + if (mount(NULL, x, NULL, MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) { + + /* Deal with mount points that are + * obstructed by a later mount */ + + if (errno != ENOENT) + return -errno; + } + + } + } +} +#endif + +int fflush_and_check(FILE *f) { + assert(f); + + errno = 0; + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +char *tempfn_xxxxxx(const char *p) { + const char *fn; + char *t; + size_t k; + + assert(p); + + t = new(char, strlen(p) + 1 + 6 + 1); + if (!t) + return NULL; + + fn = basename(p); + k = fn - p; + + strcpy(stpcpy(stpcpy(mempcpy(t, p, k), "."), fn), "XXXXXX"); + + return t; +} + +#if 0 /* NM_IGNORED */ +char *tempfn_random(const char *p) { + const char *fn; + char *t, *x; + uint64_t u; + size_t k; + unsigned i; + + assert(p); + + t = new(char, strlen(p) + 1 + 16 + 1); + if (!t) + return NULL; + + fn = basename(p); + k = fn - p; + + x = stpcpy(stpcpy(mempcpy(t, p, k), "."), fn); + + u = random_u64(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(u & 0xF); + u >>= 4; + } + + *x = 0; + + return t; +} +#endif + +/* make sure the hostname is not "localhost" */ +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 */ + + return streq(hostname, "localhost") || + streq(hostname, "localhost.") || + streq(hostname, "localdomain.") || + streq(hostname, "localdomain") || + endswith(hostname, ".localhost") || + endswith(hostname, ".localhost.") || + endswith(hostname, ".localdomain") || + endswith(hostname, ".localdomain."); +} + +#if 0 /* NM_IGNORED */ +int take_password_lock(const char *root) { + + struct flock flock = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0, + }; + + const char *path; + int fd, r; + + /* This is roughly the same as lckpwdf(), but not as awful. We + * don't want to use alarm() and signals, hence we implement + * our own trivial version of this. + * + * Note that shadow-utils also takes per-database locks in + * addition to lckpwdf(). However, we don't given that they + * are redundant as they they invoke lckpwdf() first and keep + * it during everything they do. The per-database locks are + * awfully racy, and thus we just won't do them. */ + + if (root) + path = strappenda(root, "/etc/.pwd.lock"); + else + path = "/etc/.pwd.lock"; + + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600); + if (fd < 0) + return -errno; + + r = fcntl(fd, F_SETLKW, &flock); + if (r < 0) { + safe_close(fd); + return -errno; + } + + return fd; +} + +int is_symlink(const char *path) { + struct stat info; + + if (lstat(path, &info) < 0) + return -errno; + + return !!S_ISLNK(info.st_mode); +} + +int is_dir(const char* path, bool follow) { + struct stat st; + int r; + + if (follow) + r = stat(path, &st); + else + r = lstat(path, &st); + if (r < 0) + return -errno; + + return !!S_ISDIR(st.st_mode); +} + +int unquote_first_word(const char **p, char **ret, bool relax) { + _cleanup_free_ char *s = NULL; + size_t allocated = 0, sz = 0; + + enum { + START, + VALUE, + VALUE_ESCAPE, + SINGLE_QUOTE, + SINGLE_QUOTE_ESCAPE, + DOUBLE_QUOTE, + DOUBLE_QUOTE_ESCAPE, + SPACE, + } state = START; + + assert(p); + assert(*p); + assert(ret); + + /* 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. */ + + for (;;) { + char c = **p; + + switch (state) { + + case START: + if (c == 0) + goto finish; + else if (strchr(WHITESPACE, c)) + break; + + state = VALUE; + /* fallthrough */ + + case VALUE: + if (c == 0) + goto finish; + else if (c == '\'') + state = SINGLE_QUOTE; + else if (c == '\\') + state = VALUE_ESCAPE; + else if (c == '\"') + state = DOUBLE_QUOTE; + else if (strchr(WHITESPACE, c)) + state = SPACE; + else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + + break; + + case VALUE_ESCAPE: + if (c == 0) { + if (relax) + goto finish; + return -EINVAL; + } + + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + state = VALUE; + + break; + + case SINGLE_QUOTE: + if (c == 0) { + if (relax) + goto finish; + return -EINVAL; + } else if (c == '\'') + state = VALUE; + else if (c == '\\') + state = SINGLE_QUOTE_ESCAPE; + else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + + break; + + case SINGLE_QUOTE_ESCAPE: + if (c == 0) { + if (relax) + goto finish; + return -EINVAL; + } + + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + state = SINGLE_QUOTE; + break; + + case DOUBLE_QUOTE: + if (c == 0) + return -EINVAL; + else if (c == '\"') + state = VALUE; + else if (c == '\\') + state = DOUBLE_QUOTE_ESCAPE; + else { + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + } + + break; + + case DOUBLE_QUOTE_ESCAPE: + if (c == 0) { + if (relax) + goto finish; + return -EINVAL; + } + + if (!GREEDY_REALLOC(s, allocated, sz+2)) + return -ENOMEM; + + s[sz++] = c; + state = DOUBLE_QUOTE; + break; + + case SPACE: + if (c == 0) + goto finish; + if (!strchr(WHITESPACE, c)) + goto finish; + + break; + } + + (*p) ++; + } + +finish: + if (!s) { + *ret = NULL; + return 0; + } + + s[sz] = 0; + *ret = s; + s = NULL; + + return 1; +} + +int unquote_many_words(const char **p, ...) { + 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, p); + 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 = unquote_first_word(p, &l[c], false); + 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, p); + for (i = 0; i < n; i++) { + char **v; + + v = va_arg(ap, char **); + assert(v); + + *v = l[i]; + } + va_end(ap); + + return c; +} + +int free_and_strdup(char **p, const char *s) { + char *t; + + assert(p); + + /* Replaces a string pointer with an strdup()ed new string, + * possibly freeing the old one. */ + + if (s) { + t = strdup(s); + if (!t) + return -ENOMEM; + } else + t = NULL; + + free(*p); + *p = t; + + return 0; +} + +int sethostname_idempotent(const char *s) { + int r; + char buf[HOST_NAME_MAX + 1] = {}; + + assert(s); + + r = gethostname(buf, sizeof(buf)); + if (r < 0) + return -errno; + + if (streq(buf, s)) + return 0; + + r = sethostname(s, strlen(s)); + if (r < 0) + return -errno; + + return 1; +} +#endif + diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/util.h b/src/dhcp-manager/systemd-dhcp/src/shared/util.h new file mode 100644 index 00000000..a7690655 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/util.h @@ -0,0 +1,1038 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#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 . +***/ + +#include "nm-sd-adapt.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if 0 /* NM_IGNORED */ +#if SIZEOF_PID_T == 4 +# define PID_FMT "%" PRIu32 +#elif SIZEOF_PID_T == 2 +# define PID_FMT "%" PRIu16 +#else +# error Unknown pid_t size +#endif + +#if SIZEOF_UID_T == 4 +# define UID_FMT "%" PRIu32 +#elif SIZEOF_UID_T == 2 +# define UID_FMT "%" PRIu16 +#else +# error Unknown uid_t size +#endif + +#if SIZEOF_GID_T == 4 +# define GID_FMT "%" PRIu32 +#elif SIZEOF_GID_T == 2 +# define GID_FMT "%" PRIu16 +#else +# error Unknown gid_t size +#endif + +#if SIZEOF_TIME_T == 8 +# define PRI_TIME PRIu64 +#elif SIZEOF_TIME_T == 4 +# define PRI_TIME PRIu32 +#else +# error Unknown time_t size +#endif + +#if SIZEOF_RLIM_T == 8 +# define RLIM_FMT "%" PRIu64 +#elif SIZEOF_RLIM_T == 4 +# define RLIM_FMT "%" PRIu32 +#else +# error Unknown rlim_t size +#endif +#endif + +#include "macro.h" +#if 0 /* NM_IGNORED */ +#include "missing.h" +#endif +#include "time-util.h" + +/* What is interpreted as whitespace? */ +#define WHITESPACE " \t\n\r" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;" +#define GLOB_CHARS "*?[" + +/* What characters are special in the shell? */ +/* must be escaped outside and inside double-quotes */ +#define SHELL_NEED_ESCAPE "\"\\`$" +/* can be escaped or double-quoted */ +#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;" + +#define FORMAT_BYTES_MAX 8 + +#define ANSI_HIGHLIGHT_ON "\x1B[1;39m" +#define ANSI_RED_ON "\x1B[31m" +#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m" +#define ANSI_GREEN_ON "\x1B[32m" +#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m" +#define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m" +#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m" +#define ANSI_HIGHLIGHT_OFF "\x1B[0m" +#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" + +size_t page_size(void); +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0) +#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) + +bool streq_ptr(const char *a, const char *b) _pure_; + +#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + +#define new0(t, n) ((t*) calloc((n), sizeof(t))) + +#define newa(t, n) ((t*) alloca(sizeof(t)*(n))) + +#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n))) + +#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) + +#define malloc0(n) (calloc((n), 1)) + +static inline const char* yes_no(bool b) { + return b ? "yes" : "no"; +} + +static inline const char* true_false(bool b) { + return b ? "true" : "false"; +} + +static inline const char* strempty(const char *s) { + return s ? s : ""; +} + +static inline const char* strnull(const char *s) { + return s ? s : "(null)"; +} + +static inline const char *strna(const char *s) { + return s ? s : "n/a"; +} + +static inline bool isempty(const char *p) { + return !p || !p[0]; +} + +static inline char *startswith(const char *s, const char *prefix) { + size_t l; + + l = strlen(prefix); + if (strncmp(s, prefix, l) == 0) + return (char*) s + l; + + return NULL; +} + +static inline char *startswith_no_case(const char *s, const char *prefix) { + size_t l; + + l = strlen(prefix); + if (strncasecmp(s, prefix, l) == 0) + return (char*) s + l; + + return NULL; +} + +char *endswith(const char *s, const char *postfix) _pure_; + +char *first_word(const char *s, const char *word) _pure_; + +int close_nointr(int fd); +int safe_close(int fd); +void safe_close_pair(int p[]); + +void close_many(const int fds[], unsigned n_fd); + +int parse_size(const char *t, off_t base, off_t *size); + +int parse_boolean(const char *v) _pure_; +int parse_pid(const char *s, pid_t* ret_pid); +int parse_uid(const char *s, uid_t* ret_uid); +#define parse_gid(s, ret_uid) parse_uid(s, ret_uid) + +int safe_atou(const char *s, unsigned *ret_u); +int safe_atoi(const char *s, int *ret_i); + +int safe_atollu(const char *s, unsigned long long *ret_u); +int safe_atolli(const char *s, long long int *ret_i); + +int safe_atod(const char *s, double *ret_d); + +int safe_atou8(const char *s, uint8_t *ret); + +#if LONG_MAX == INT_MAX +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(int)); + return safe_atoi(s, (int*) ret_u); +} +#else +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_u); +} +#endif + +static inline int safe_atou32(const char *s, uint32_t *ret_u) { + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} + +static inline int safe_atoi32(const char *s, int32_t *ret_i) { + assert_cc(sizeof(int32_t) == sizeof(int)); + return safe_atoi(s, (int*) ret_i); +} + +static inline int safe_atou64(const char *s, uint64_t *ret_u) { + assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} + +static inline int safe_atoi64(const char *s, int64_t *ret_i) { + assert_cc(sizeof(int64_t) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_i); +} + +int safe_atou16(const char *s, uint16_t *ret); +int safe_atoi16(const char *s, int16_t *ret); + +const char* split(const char **state, size_t *l, const char *separator, bool quoted); + +#define FOREACH_WORD(word, length, s, state) \ + _FOREACH_WORD(word, length, s, WHITESPACE, false, state) + +#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \ + _FOREACH_WORD(word, length, s, separator, false, state) + +#define FOREACH_WORD_QUOTED(word, length, s, state) \ + _FOREACH_WORD(word, length, s, WHITESPACE, true, state) + +#define _FOREACH_WORD(word, length, s, separator, quoted, state) \ + for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted))) + +pid_t get_parent_of_pid(pid_t pid, pid_t *ppid); +int get_starttime_of_pid(pid_t pid, unsigned long long *st); + +char *strappend(const char *s, const char *suffix); +char *strnappend(const char *s, const char *suffix, size_t length); + +char *replace_env(const char *format, char **env); +char **replace_env_argv(char **argv, char **env); + +int readlinkat_malloc(int fd, const char *p, char **ret); +int readlink_malloc(const char *p, char **r); +int readlink_value(const char *p, char **ret); +int readlink_and_make_absolute(const char *p, char **r); +int readlink_and_canonicalize(const char *p, char **r); + +int reset_all_signal_handlers(void); +int reset_signal_mask(void); + +char *strstrip(char *s); +char *delete_chars(char *s, const char *bad); +char *truncate_nl(char *s); + +char *file_in_same_dir(const char *path, const char *filename); + +int rmdir_parents(const char *path, const char *stop); + +int get_process_state(pid_t pid); +int get_process_comm(pid_t pid, char **name); +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line); +int get_process_exe(pid_t pid, char **name); +int get_process_uid(pid_t pid, uid_t *uid); +int get_process_gid(pid_t pid, gid_t *gid); +int get_process_capeff(pid_t pid, char **capeff); + +char hexchar(int x) _const_; +int unhexchar(char c) _const_; +char octchar(int x) _const_; +int unoctchar(char c) _const_; +char decchar(int x) _const_; +int undecchar(char c) _const_; + +char *cescape(const char *s); +char *cunescape(const char *s); +char *cunescape_length(const char *s, size_t length); +char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix); + +char *xescape(const char *s, const char *bad); + +char *ascii_strlower(char *path); + +bool dirent_is_file(const struct dirent *de) _pure_; +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; + +bool ignore_file(const char *filename) _pure_; + +bool chars_intersect(const char *a, const char *b) _pure_; + +int make_stdio(int fd); +int make_null_stdio(void); +int make_console_stdio(void); + +int dev_urandom(void *p, size_t n); +void random_bytes(void *p, size_t n); +void initialize_srand(void); + +static inline uint64_t random_u64(void) { + uint64_t u; + random_bytes(&u, sizeof(u)); + return u; +} + +static inline uint32_t random_u32(void) { + uint32_t u; + random_bytes(&u, sizeof(u)); + return u; +} + +/* For basic lookup tables with strictly enumerated entries */ +#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + scope const char *name##_to_string(type i) { \ + if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ + return NULL; \ + return name##_table[i]; \ + } \ + scope type name##_from_string(const char *s) { \ + type i; \ + if (!s) \ + return (type) -1; \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ + return (type) -1; \ + } \ + 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) + +/* 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) { \ + char *s; \ + int r; \ + if (i < 0 || i > max) \ + return -ERANGE; \ + if (i < (type) ELEMENTSOF(name##_table)) { \ + s = strdup(name##_table[i]); \ + if (!s) \ + return log_oom(); \ + } else { \ + r = asprintf(&s, "%u", i); \ + if (r < 0) \ + return log_oom(); \ + } \ + *str = s; \ + return 0; \ + } \ + type name##_from_string(const char *s) { \ + type i; \ + unsigned u = 0; \ + assert(s); \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ + if (safe_atou(s, &u) >= 0 && u <= max) \ + return (type) u; \ + return (type) -1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +int fd_nonblock(int fd, bool nonblock); +int fd_cloexec(int fd, bool cloexec); + +int close_all_fds(const int except[], unsigned n_except); + +bool fstype_is_network(const char *fstype); + +int chvt(int vt); + +int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl); +int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4); +int ask_string(char **ret, const char *text, ...) _printf_(2, 3); + +int reset_terminal_fd(int fd, bool switch_to_text); +int reset_terminal(const char *name); + +int open_terminal(const char *name, int mode); +int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout); +int release_terminal(void); + +int flush_fd(int fd); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path); + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); + +bool is_device_path(const char *path); + +int dir_is_empty(const char *path); +char* dirname_malloc(const char *path); + +void rename_process(const char name[8]); + +void sigset_add_many(sigset_t *ss, ...); +int sigprocmask_many(int how, ...); + +bool hostname_is_set(void); + +char* lookup_uid(uid_t uid); +char* gethostname_malloc(void); +char* getlogname_malloc(void); +char* getusername_malloc(void); + +int getttyname_malloc(int fd, char **r); +int getttyname_harder(int fd, char **r); + +int get_ctty_devnr(pid_t pid, dev_t *d); +int get_ctty(pid_t, dev_t *_devnr, char **r); + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid); + +int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); +int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev); +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); +int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); + +int pipe_eof(int fd); + +cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) _printf_(4,0); +int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) _printf_(4,5); + +int fd_columns(int fd); +unsigned columns(void); +int fd_lines(int fd); +unsigned lines(void); +void columns_lines_cache_reset(int _unused_ signum); + +bool on_tty(void); + +static inline const char *ansi_highlight(void) { + return on_tty() ? ANSI_HIGHLIGHT_ON : ""; +} + +static inline const char *ansi_highlight_red(void) { + return on_tty() ? ANSI_HIGHLIGHT_RED_ON : ""; +} + +static inline const char *ansi_highlight_green(void) { + return on_tty() ? ANSI_HIGHLIGHT_GREEN_ON : ""; +} + +static inline const char *ansi_highlight_yellow(void) { + return on_tty() ? ANSI_HIGHLIGHT_YELLOW_ON : ""; +} + +static inline const char *ansi_highlight_blue(void) { + return on_tty() ? ANSI_HIGHLIGHT_BLUE_ON : ""; +} + +static inline const char *ansi_highlight_off(void) { + return on_tty() ? ANSI_HIGHLIGHT_OFF : ""; +} + +int files_same(const char *filea, const char *fileb); + +int running_in_chroot(void); + +char *ellipsize(const char *s, size_t length, unsigned percent); + /* bytes columns */ +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent); + +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); +int touch(const char *path); + +char *unquote(const char *s, const char *quotes); +char *normalize_env_assignment(const char *s); + +int wait_for_terminate(pid_t pid, siginfo_t *status); +int wait_for_terminate_and_warn(const char *name, pid_t pid); + +noreturn void freeze(void); + +bool null_or_empty(struct stat *st) _pure_; +int null_or_empty_path(const char *fn); +int null_or_empty_fd(int fd); + +DIR *xopendirat(int dirfd, const char *name, int flags); + +char *fstab_node_to_udev_node(const char *p); + +char *resolve_dev_console(char **active); +bool tty_is_vc(const char *tty); +bool tty_is_vc_resolve(const char *tty); +bool tty_is_console(const char *tty) _pure_; +int vtnr_from_tty(const char *tty); +const char *default_term_for_tty(const char *tty); + +void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[]); + +int kill_and_sigcont(pid_t pid, int sig); + +bool nulstr_contains(const char*nulstr, const char *needle); + +bool plymouth_running(void); + +bool hostname_is_valid(const char *s) _pure_; +char* hostname_cleanup(char *s, bool lowercase); + +bool machine_name_is_valid(const char *s) _pure_; + +char* strshorten(char *s, size_t l); + +int terminal_vhangup_fd(int fd); +int terminal_vhangup(const char *name); + +int vt_disallocate(const char *name); + +int symlink_atomic(const char *from, const char *to); +int mknod_atomic(const char *path, mode_t mode, dev_t dev); +int mkfifo_atomic(const char *path, mode_t mode); + +int fchmod_umask(int fd, mode_t mode); + +bool display_is_local(const char *display) _pure_; +int socket_from_display(const char *display, char **path); + +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell); +int get_group_creds(const char **groupname, gid_t *gid); + +int in_gid(gid_t gid); +int in_group(const char *name); + +char* uid_to_name(uid_t uid); +char* gid_to_name(gid_t gid); + +int glob_exists(const char *path); +int glob_extend(char ***strv, const char *path); + +int dirent_ensure_type(DIR *d, struct dirent *de); + +int get_files_in_directory(const char *path, char ***list); + +char *strjoin(const char *x, ...) _sentinel_; + +bool is_main_thread(void); + +static inline bool _pure_ in_charset(const char *s, const char* charset) { + assert(s); + assert(charset); + return s[strspn(s, charset)] == '\0'; +} + +int block_get_whole_disk(dev_t d, dev_t *ret); + +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + +#define NULSTR_FOREACH_PAIR(i, j, l) \ + for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) + +int ioprio_class_to_string_alloc(int i, char **s); +int ioprio_class_from_string(const char *s); + +const char *sigchld_code_to_string(int i) _const_; +int sigchld_code_from_string(const char *s) _pure_; + +int log_facility_unshifted_to_string_alloc(int i, char **s); +int log_facility_unshifted_from_string(const char *s); + +int log_level_to_string_alloc(int i, char **s); +int log_level_from_string(const char *s); + +int sched_policy_to_string_alloc(int i, char **s); +int sched_policy_from_string(const char *s); + +const char *rlimit_to_string(int i) _const_; +int rlimit_from_string(const char *s) _pure_; + +int ip_tos_to_string_alloc(int i, char **s); +int ip_tos_from_string(const char *s); + +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); + +extern int saved_argc; +extern char **saved_argv; + +bool kexec_loaded(void); + +int prot_from_flags(int flags) _const_; + +char *format_bytes(char *buf, size_t l, off_t t); + +int fd_wait_for_event(int fd, int event, usec_t timeout); + +void* memdup(const void *p, size_t l) _alloc_(2); + +int is_kernel_thread(pid_t pid); + +int fd_inc_sndbuf(int fd, size_t n); +int fd_inc_rcvbuf(int fd, size_t n); + +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); + +int setrlimit_closest(int resource, const struct rlimit *rlim); + +int getenv_for_pid(pid_t pid, const char *field, char **_value); + +bool is_valid_documentation_url(const char *url) _pure_; + +bool in_initrd(void); + +void warn_melody(void); + +int get_home_dir(char **ret); +int get_shell(char **_ret); + +static inline void freep(void *p) { + free(*(void**) p); +} + +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) { \ + if (*p) \ + func(*p); \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +static inline void closep(int *fd) { + safe_close(*fd); +} + +static inline void umaskp(mode_t *u) { + umask(*u); +} + +static inline void close_pairp(int (*p)[2]) { + safe_close_pair(*p); +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, fclose); +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose); +DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir); +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent); + +#define _cleanup_free_ _cleanup_(freep) +#define _cleanup_close_ _cleanup_(closep) +#define _cleanup_umask_ _cleanup_(umaskp) +#define _cleanup_globfree_ _cleanup_(globfree) +#define _cleanup_fclose_ _cleanup_(fclosep) +#define _cleanup_pclose_ _cleanup_(pclosep) +#define _cleanup_closedir_ _cleanup_(closedirp) +#define _cleanup_endmntent_ _cleanup_(endmntentp) +#define _cleanup_close_pair_ _cleanup_(close_pairp) + +_malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) { + if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) + return NULL; + + return malloc(a * b); +} + +_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) { + if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) + return NULL; + + return realloc(p, a * b); +} + +_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) { + if (_unlikely_(b != 0 && a > ((size_t) -1) / b)) + return NULL; + + return memdup(p, a * b); +} + +bool filename_is_safe(const char *p) _pure_; +bool path_is_safe(const char *p) _pure_; +bool string_is_safe(const char *p) _pure_; +bool string_has_cc(const char *p, const char *ok) _pure_; + +/** + * Check if a string contains any glob patterns. + */ +_pure_ static inline bool string_is_glob(const char *p) { + return !!strpbrk(p, GLOB_CHARS); +} + +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); + +bool is_locale_utf8(void); + +typedef enum DrawSpecialChar { + DRAW_TREE_VERTICAL, + DRAW_TREE_BRANCH, + DRAW_TREE_RIGHT, + DRAW_TREE_SPACE, + DRAW_TRIANGULAR_BULLET, + DRAW_BLACK_CIRCLE, + DRAW_ARROW, + DRAW_DASH, + _DRAW_SPECIAL_CHAR_MAX +} DrawSpecialChar; + +const char *draw_special_char(DrawSpecialChar ch); + +char *strreplace(const char *text, const char *old_string, const char *new_string); + +char *strip_tab_ansi(char **p, size_t *l); + +int on_ac_power(void); + +int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f); +int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f); + +#define FOREACH_LINE(line, f, on_error) \ + for (;;) \ + if (!fgets(line, sizeof(line), f)) { \ + if (ferror(f)) { \ + on_error; \ + } \ + break; \ + } else + +#define FOREACH_DIRENT(de, d, on_error) \ + for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ + if (!de) { \ + if (errno > 0) { \ + on_error; \ + } \ + break; \ + } else if (ignore_file((de)->d_name)) \ + continue; \ + else + +static inline void *mempset(void *s, int c, size_t n) { + memset(s, c, n); + return (uint8_t*)s + n; +} + +char *hexmem(const void *p, size_t l); +void *unhexmem(const char *p, size_t l); + +char *strextend(char **x, ...) _sentinel_; +char *strrep(const char *s, unsigned n); + +void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size); +void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); +#define GREEDY_REALLOC(array, allocated, need) \ + greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +#define GREEDY_REALLOC0(array, allocated, need) \ + greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +static inline void _reset_errno_(int *saved_errno) { + errno = *saved_errno; +} + +#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno + +static inline int negative_errno(void) { + /* This helper should be used to shut up gcc if you know 'errno' is + * negative. Instead of "return -errno;", use "return negative_errno();" + * It will suppress bogus gcc warnings in case it assumes 'errno' might + * be 0 and thus the caller's error-handling might not be triggered. */ + assert_return(errno > 0, -EINVAL); + return -errno; +} + +struct _umask_struct_ { + mode_t mask; + bool quit; +}; + +static inline void _reset_umask_(struct _umask_struct_ *s) { + umask(s->mask); +}; + +#define RUN_WITH_UMASK(mask) \ + for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \ + !_saved_umask_.quit ; \ + _saved_umask_.quit = true) + +static inline unsigned u64log2(uint64_t n) { +#if __SIZEOF_LONG_LONG__ == 8 + return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0; +#else +#error "Wut?" +#endif +} + +static inline unsigned u32ctz(uint32_t n) { +#if __SIZEOF_INT__ == 4 + return __builtin_ctz(n); +#else +#error "Wut?" +#endif +} + +static inline int log2i(int x) { + assert(x > 0); + + return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u(unsigned x) { + assert(x > 0); + + return sizeof(unsigned) * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u_round_up(unsigned x) { + assert(x > 0); + + if (x == 1) + return 0; + + return log2u(x - 1) + 1; +} + +static inline bool logind_running(void) { + return access("/run/systemd/seats/", F_OK) >= 0; +} + +#define DECIMAL_STR_WIDTH(x) \ + ({ \ + typeof(x) _x_ = (x); \ + unsigned ans = 1; \ + while (_x_ /= 10) \ + ans++; \ + ans; \ + }) + +int unlink_noerrno(const char *path); + +#define alloca0(n) \ + ({ \ + char *_new_; \ + size_t _len_ = n; \ + _new_ = alloca(_len_); \ + (void *) memset(_new_, 0, _len_); \ + }) + +#define alloca_align(size, align) \ + ({ \ + void *_ptr_; \ + size_t _mask_ = (align) - 1; \ + _ptr_ = alloca((size) + _mask_); \ + (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \ + }) + +#define alloca0_align(size, align) \ + ({ \ + void *_new_; \ + size_t _size_ = (size); \ + _new_ = alloca_align(_size_, (align)); \ + (void*)memset(_new_, 0, _size_); \ + }) + +#define strappenda(a, ...) \ + ({ \ + int _len = strlen(a); \ + unsigned _i; \ + char *_d_, *_p_; \ + const char *_appendees_[] = { __VA_ARGS__ }; \ + for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \ + _len += strlen(_appendees_[_i]); \ + _d_ = alloca(_len + 1); \ + _p_ = stpcpy(_d_, a); \ + for (_i = 0; _i < ELEMENTSOF(_appendees_); _i++) \ + _p_ = stpcpy(_p_, _appendees_[_i]); \ + _d_; \ + }) + +#define procfs_file_alloca(pid, field) \ + ({ \ + pid_t _pid_ = (pid); \ + const char *_r_; \ + if (_pid_ == 0) { \ + _r_ = ("/proc/self/" field); \ + } else { \ + _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \ + sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \ + } \ + _r_; \ + }) + +struct _locale_struct_ { + locale_t saved_locale; + locale_t new_locale; + bool quit; +}; + +static inline void _reset_locale_(struct _locale_struct_ *s) { + PROTECT_ERRNO; + if (s->saved_locale != (locale_t) 0) + uselocale(s->saved_locale); + if (s->new_locale != (locale_t) 0) + freelocale(s->new_locale); +} + +#define RUN_WITH_LOCALE(mask, loc) \ + for (_cleanup_(_reset_locale_) struct _locale_struct_ _saved_locale_ = { (locale_t) 0, (locale_t) 0, false }; \ + ({ \ + if (!_saved_locale_.quit) { \ + PROTECT_ERRNO; \ + _saved_locale_.new_locale = newlocale((mask), (loc), (locale_t) 0); \ + if (_saved_locale_.new_locale != (locale_t) 0) \ + _saved_locale_.saved_locale = uselocale(_saved_locale_.new_locale); \ + } \ + !_saved_locale_.quit; }) ; \ + _saved_locale_.quit = true) + +bool id128_is_valid(const char *s) _pure_; + +int split_pair(const char *s, const char *sep, char **l, char **r); + +int shall_restore_state(void); + +/** + * Normal qsort requires base to be nonnull. Here were require + * that only if nmemb > 0. + */ +static inline void qsort_safe(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)) { + if (nmemb) { + assert(base); + qsort(base, nmemb, size, compar); + } +} + +int proc_cmdline(char **ret); +int parse_proc_cmdline(int (*parse_word)(const char *key, const char *value)); + +int container_get_leader(const char *machine, pid_t *pid); + +int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd); +int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd); + +bool pid_is_alive(pid_t pid); +bool pid_is_unwaited(pid_t pid); + +#if 0 /* NM_IGNORED */ +int getpeercred(int fd, struct ucred *ucred); +int getpeersec(int fd, char **ret); +#endif + +int writev_safe(int fd, const struct iovec *w, int j); + +int mkostemp_safe(char *pattern, int flags); +int open_tmpfile(const char *path, int flags); + +int fd_warn_permissions(const char *path, int fd); + +unsigned long personality_from_string(const char *p); +const char *personality_to_string(unsigned long); + +uint64_t physical_memory(void); + +char* mount_test_option(const char *haystack, const char *needle); + +void hexdump(FILE *f, const void *p, size_t s); + +#if 0 /* NM_IGNORED */ +union file_handle_union { + struct file_handle handle; + char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ]; +}; +#endif + +int update_reboot_param_file(const char *param); + +int umount_recursive(const char *target, int flags); + +int bind_remount_recursive(const char *prefix, bool ro); + +int fflush_and_check(FILE *f); + +char *tempfn_xxxxxx(const char *p); +char *tempfn_random(const char *p); + +bool is_localhost(const char *hostname); + +int take_password_lock(const char *root); + +int is_symlink(const char *path); +int is_dir(const char *path, bool follow); + +int unquote_first_word(const char **p, char **ret, bool relax); +int unquote_many_words(const char **p, ...) _sentinel_; + +int free_and_strdup(char **p, const char *s); + +int sethostname_idempotent(const char *s); diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h b/src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h new file mode 100644 index 00000000..896a027e --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h @@ -0,0 +1,78 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdcommonhfoo +#define foosdcommonhfoo + +/*** + This file is part of systemd. + + Copyright 2013 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 . +***/ + +/* This is a private header; never even think of including this directly! */ + +#if __INCLUDE_LEVEL__ <= 1 +#error "Do not include _sd-common.h directly; it is a private header." +#endif + +#ifndef _sd_printf_ +# if __GNUC__ >= 4 +# define _sd_printf_(a,b) __attribute__ ((format (printf, a, b))) +# else +# define _sd_printf_(a,b) +# endif +#endif + +#ifndef _sd_sentinel_ +# define _sd_sentinel_ __attribute__((sentinel)) +#endif + +#ifndef _sd_packed_ +# define _sd_packed_ __attribute__((packed)) +#endif + +#ifndef _sd_pure_ +# define _sd_pure_ __attribute__((pure)) +#endif + +#ifndef _SD_STRINGIFY +# define _SD_XSTRINGIFY(x) #x +# define _SD_STRINGIFY(x) _SD_XSTRINGIFY(x) +#endif + +#ifndef _SD_BEGIN_DECLARATIONS +# ifdef __cplusplus +# define _SD_BEGIN_DECLARATIONS \ + extern "C" { \ + struct __useless_struct_to_allow_trailing_semicolon__ +# else +# define _SD_BEGIN_DECLARATIONS \ + struct __useless_struct_to_allow_trailing_semicolon__ +# endif +#endif + +#ifndef _SD_END_DECLARATIONS +# ifdef __cplusplus +# define _SD_END_DECLARATIONS \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ +# else +# define _SD_END_DECLARATIONS \ + struct __useless_struct_to_allow_trailing_semicolon__ +# endif +#endif + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h new file mode 100644 index 00000000..951662e5 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h @@ -0,0 +1,75 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddhcpclienthfoo +#define foosddhcpclienthfoo + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include +#include + +#include "sd-event.h" +#include "sd-dhcp-lease.h" + +enum { + DHCP_EVENT_STOP = 0, + DHCP_EVENT_IP_ACQUIRE = 1, + DHCP_EVENT_IP_CHANGE = 2, + DHCP_EVENT_EXPIRED = 3, + DHCP_EVENT_RENEW = 4, +}; + +typedef struct sd_dhcp_client sd_dhcp_client; + +typedef void (*sd_dhcp_client_cb_t)(sd_dhcp_client *client, int event, + void *userdata); +int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_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_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); + +sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client); +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, int priority); +int sd_dhcp_client_detach_event(sd_dhcp_client *client); +sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client); + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h new file mode 100644 index 00000000..4296b91d --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h @@ -0,0 +1,54 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddhcpleasehfoo +#define foosddhcpleasehfoo + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + 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 . +***/ + +#include +#include + +typedef struct sd_dhcp_lease sd_dhcp_lease; +struct sd_dhcp_route; + +sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease); +sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease); + +int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr); +int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime); +int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr); +int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr); +int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr); +int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr); +int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr); +int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); +int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); +int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); +int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname); +int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path); +int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routesgn); +int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, + size_t *client_id_len); + +int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); +int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h new file mode 100644 index 00000000..38c1c3fb --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddhcp6clienthfoo +#define foosddhcp6clienthfoo + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include + +#include "sd-event.h" + +#include "sd-dhcp6-lease.h" + +enum { + DHCP6_EVENT_STOP = 0, + DHCP6_EVENT_RESEND_EXPIRE = 10, + DHCP6_EVENT_RETRANS_MAX = 11, + DHCP6_EVENT_IP_ACQUIRE = 12, +}; + +typedef struct sd_dhcp6_client sd_dhcp6_client; + +typedef void (*sd_dhcp6_client_cb_t)(sd_dhcp6_client *client, int event, + void *userdata); +int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, + sd_dhcp6_client_cb_t cb, void *userdata); + +int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index); +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 type, uint8_t *duid, + size_t duid_len); +int sd_dhcp6_client_set_ifname(sd_dhcp6_client *client, const char *ifname); +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_attach_event(sd_dhcp6_client *client, sd_event *event, + int 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); +sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client); +int sd_dhcp6_client_new(sd_dhcp6_client **ret); + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h new file mode 100644 index 00000000..1126f1ac --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h @@ -0,0 +1,42 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddhcp6leasehfoo +#define foosddhcp6leasehfoo + +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014 Intel Corporation. All rights reserved. + + 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 . +***/ + +#include + +typedef struct sd_dhcp6_lease sd_dhcp6_lease; + +int sd_dhcp6_lease_get_first_address(sd_dhcp6_lease *lease, + struct in6_addr *addr, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid); +int sd_dhcp6_lease_get_next_address(sd_dhcp6_lease *lease, + struct in6_addr *addr, + uint32_t *lifetime_preferred, + uint32_t *lifetime_valid); + +sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease); +sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease); + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h new file mode 100644 index 00000000..25a10f99 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h @@ -0,0 +1,135 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdeventhfoo +#define foosdeventhfoo + +/*** + This file is part of systemd. + + Copyright 2013 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 . +***/ + +#include +#include +#include +#include +#include + +#include "_sd-common.h" + +/* + Why is this better than pure epoll? + + - Supports event source prioritization + - Scales better with a large number of time events because it does not require one timerfd each + - Automatically tries to coalesce timer events system-wide + - Handles signals and child PIDs +*/ + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_event sd_event; +typedef struct sd_event_source sd_event_source; + +enum { + SD_EVENT_OFF = 0, + SD_EVENT_ON = 1, + SD_EVENT_ONESHOT = -1 +}; + +enum { + SD_EVENT_PASSIVE, + SD_EVENT_PREPARED, + SD_EVENT_PENDING, + SD_EVENT_RUNNING, + SD_EVENT_EXITING, + SD_EVENT_FINISHED +}; + +enum { + /* And everything in-between and outside is good too */ + SD_EVENT_PRIORITY_IMPORTANT = -100, + SD_EVENT_PRIORITY_NORMAL = 0, + SD_EVENT_PRIORITY_IDLE = 100 +}; + +typedef int (*sd_event_handler_t)(sd_event_source *s, void *userdata); +typedef int (*sd_event_io_handler_t)(sd_event_source *s, int fd, uint32_t revents, void *userdata); +typedef int (*sd_event_time_handler_t)(sd_event_source *s, uint64_t usec, void *userdata); +typedef int (*sd_event_signal_handler_t)(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata); +typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si, void *userdata); + +int sd_event_default(sd_event **e); + +int sd_event_new(sd_event **e); +sd_event* sd_event_ref(sd_event *e); +sd_event* sd_event_unref(sd_event *e); + +int sd_event_add_io(sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata); +int sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); +int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); +int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); +int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); +int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); +int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + +int sd_event_prepare(sd_event *e); +int sd_event_wait(sd_event *e, uint64_t timeout); +int sd_event_dispatch(sd_event *e); +int sd_event_run(sd_event *e, uint64_t timeout); +int sd_event_loop(sd_event *e); +int sd_event_exit(sd_event *e, int code); + +int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec); + +int sd_event_get_fd(sd_event *e); +int sd_event_get_state(sd_event *e); +int sd_event_get_tid(sd_event *e, pid_t *tid); +int sd_event_get_exit_code(sd_event *e, int *code); +int sd_event_set_watchdog(sd_event *e, int b); +int sd_event_get_watchdog(sd_event *e); + +sd_event_source* sd_event_source_ref(sd_event_source *s); +sd_event_source* sd_event_source_unref(sd_event_source *s); + +sd_event *sd_event_source_get_event(sd_event_source *s); +void* sd_event_source_get_userdata(sd_event_source *s); +void* sd_event_source_set_userdata(sd_event_source *s, void *userdata); + +int sd_event_source_set_description(sd_event_source *s, const char *description); +int sd_event_source_get_description(sd_event_source *s, const char **description); +int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback); +int sd_event_source_get_pending(sd_event_source *s); +int sd_event_source_get_priority(sd_event_source *s, int64_t *priority); +int sd_event_source_set_priority(sd_event_source *s, int64_t priority); +int sd_event_source_get_enabled(sd_event_source *s, int *enabled); +int sd_event_source_set_enabled(sd_event_source *s, int enabled); +int sd_event_source_get_io_fd(sd_event_source *s); +int sd_event_source_set_io_fd(sd_event_source *s, int fd); +int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events); +int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); +int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); +int sd_event_source_get_time(sd_event_source *s, uint64_t *usec); +int sd_event_source_set_time(sd_event_source *s, uint64_t usec); +int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec); +int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec); +int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); +int sd_event_source_get_signal(sd_event_source *s); +int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid); + +_SD_END_DECLARATIONS; + +#endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h new file mode 100644 index 00000000..4fdbf3ab --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h @@ -0,0 +1,113 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdid128hfoo +#define foosdid128hfoo + +/*** + This file is part of systemd. + + Copyright 2011 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 . +***/ + +#include +#include + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +/* 128-bit ID APIs. See sd-id128(3) for more information. */ + +typedef union sd_id128 sd_id128_t; + +union sd_id128 { + uint8_t bytes[16]; + uint64_t qwords[2]; +}; + +#define SD_ID128_STRING_MAX 33 + +char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]); + +int sd_id128_from_string(const char *s, sd_id128_t *ret); + +int sd_id128_randomize(sd_id128_t *ret); + +int sd_id128_get_machine(sd_id128_t *ret); + +int sd_id128_get_boot(sd_id128_t *ret); + +#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + ((const sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ + 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }}) + +#define SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ + 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }} + +/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16 + * times. It is hence not a good idea to call this macro with an + * expensive function as paramater or an expression with side + * effects */ + +#define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" +#define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + +#define SD_ID128_CONST_STR(x) \ + ((const char[SD_ID128_STRING_MAX]) { \ + ((x).bytes[0] >> 4) >= 10 ? 'a' + ((x).bytes[0] >> 4) - 10 : '0' + ((x).bytes[0] >> 4), \ + ((x).bytes[0] & 15) >= 10 ? 'a' + ((x).bytes[0] & 15) - 10 : '0' + ((x).bytes[0] & 15), \ + ((x).bytes[1] >> 4) >= 10 ? 'a' + ((x).bytes[1] >> 4) - 10 : '0' + ((x).bytes[1] >> 4), \ + ((x).bytes[1] & 15) >= 10 ? 'a' + ((x).bytes[1] & 15) - 10 : '0' + ((x).bytes[1] & 15), \ + ((x).bytes[2] >> 4) >= 10 ? 'a' + ((x).bytes[2] >> 4) - 10 : '0' + ((x).bytes[2] >> 4), \ + ((x).bytes[2] & 15) >= 10 ? 'a' + ((x).bytes[2] & 15) - 10 : '0' + ((x).bytes[2] & 15), \ + ((x).bytes[3] >> 4) >= 10 ? 'a' + ((x).bytes[3] >> 4) - 10 : '0' + ((x).bytes[3] >> 4), \ + ((x).bytes[3] & 15) >= 10 ? 'a' + ((x).bytes[3] & 15) - 10 : '0' + ((x).bytes[3] & 15), \ + ((x).bytes[4] >> 4) >= 10 ? 'a' + ((x).bytes[4] >> 4) - 10 : '0' + ((x).bytes[4] >> 4), \ + ((x).bytes[4] & 15) >= 10 ? 'a' + ((x).bytes[4] & 15) - 10 : '0' + ((x).bytes[4] & 15), \ + ((x).bytes[5] >> 4) >= 10 ? 'a' + ((x).bytes[5] >> 4) - 10 : '0' + ((x).bytes[5] >> 4), \ + ((x).bytes[5] & 15) >= 10 ? 'a' + ((x).bytes[5] & 15) - 10 : '0' + ((x).bytes[5] & 15), \ + ((x).bytes[6] >> 4) >= 10 ? 'a' + ((x).bytes[6] >> 4) - 10 : '0' + ((x).bytes[6] >> 4), \ + ((x).bytes[6] & 15) >= 10 ? 'a' + ((x).bytes[6] & 15) - 10 : '0' + ((x).bytes[6] & 15), \ + ((x).bytes[7] >> 4) >= 10 ? 'a' + ((x).bytes[7] >> 4) - 10 : '0' + ((x).bytes[7] >> 4), \ + ((x).bytes[7] & 15) >= 10 ? 'a' + ((x).bytes[7] & 15) - 10 : '0' + ((x).bytes[7] & 15), \ + ((x).bytes[8] >> 4) >= 10 ? 'a' + ((x).bytes[8] >> 4) - 10 : '0' + ((x).bytes[8] >> 4), \ + ((x).bytes[8] & 15) >= 10 ? 'a' + ((x).bytes[8] & 15) - 10 : '0' + ((x).bytes[8] & 15), \ + ((x).bytes[9] >> 4) >= 10 ? 'a' + ((x).bytes[9] >> 4) - 10 : '0' + ((x).bytes[9] >> 4), \ + ((x).bytes[9] & 15) >= 10 ? 'a' + ((x).bytes[9] & 15) - 10 : '0' + ((x).bytes[9] & 15), \ + ((x).bytes[10] >> 4) >= 10 ? 'a' + ((x).bytes[10] >> 4) - 10 : '0' + ((x).bytes[10] >> 4), \ + ((x).bytes[10] & 15) >= 10 ? 'a' + ((x).bytes[10] & 15) - 10 : '0' + ((x).bytes[10] & 15), \ + ((x).bytes[11] >> 4) >= 10 ? 'a' + ((x).bytes[11] >> 4) - 10 : '0' + ((x).bytes[11] >> 4), \ + ((x).bytes[11] & 15) >= 10 ? 'a' + ((x).bytes[11] & 15) - 10 : '0' + ((x).bytes[11] & 15), \ + ((x).bytes[12] >> 4) >= 10 ? 'a' + ((x).bytes[12] >> 4) - 10 : '0' + ((x).bytes[12] >> 4), \ + ((x).bytes[12] & 15) >= 10 ? 'a' + ((x).bytes[12] & 15) - 10 : '0' + ((x).bytes[12] & 15), \ + ((x).bytes[13] >> 4) >= 10 ? 'a' + ((x).bytes[13] >> 4) - 10 : '0' + ((x).bytes[13] >> 4), \ + ((x).bytes[13] & 15) >= 10 ? 'a' + ((x).bytes[13] & 15) - 10 : '0' + ((x).bytes[13] & 15), \ + ((x).bytes[14] >> 4) >= 10 ? 'a' + ((x).bytes[14] >> 4) - 10 : '0' + ((x).bytes[14] >> 4), \ + ((x).bytes[14] & 15) >= 10 ? 'a' + ((x).bytes[14] & 15) - 10 : '0' + ((x).bytes[14] & 15), \ + ((x).bytes[15] >> 4) >= 10 ? 'a' + ((x).bytes[15] >> 4) - 10 : '0' + ((x).bytes[15] >> 4), \ + ((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \ + 0 }) + +_sd_pure_ static inline int sd_id128_equal(sd_id128_t a, sd_id128_t b) { + return memcmp(&a, &b, 16) == 0; +} + +#define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) + +_SD_END_DECLARATIONS; + +#endif diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am index 6ef828d5..9dc5dcb1 100644 --- a/src/dhcp-manager/tests/Makefile.am +++ b/src/dhcp-manager/tests/Makefile.am @@ -1,27 +1,43 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I$(top_srcdir)/src/dhcp-manager \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/platform \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ -DTESTDIR="\"$(abs_srcdir)\"" -noinst_PROGRAMS = test-dhcp-dhclient +noinst_PROGRAMS = \ + test-dhcp-dhclient \ + test-dhcp-utils -####### policy /etc/hosts test ####### +####### dhclient leases test ####### test_dhcp_dhclient_SOURCES = \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.h \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.h \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c \ test-dhcp-dhclient.c test_dhcp_dhclient_LDADD = \ $(top_builddir)/src/libNetworkManager.la -TESTS = test-dhcp-dhclient +####### DHCP utils test ####### + +test_dhcp_utils_SOURCES = \ + test-dhcp-utils.c + +test_dhcp_utils_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +################################# + +TESTS = test-dhcp-dhclient test-dhcp-utils EXTRA_DIST = \ test-dhclient-duid.leases \ diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in index d445838f..c0324e30 100644 --- a/src/dhcp-manager/tests/Makefile.in +++ b/src/dhcp-manager/tests/Makefile.in @@ -78,8 +78,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) -TESTS = test-dhcp-dhclient$(EXEEXT) +noinst_PROGRAMS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) +TESTS = test-dhcp-dhclient$(EXEEXT) test-dhcp-utils$(EXEEXT) subdir = src/dhcp-manager/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -104,7 +104,8 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am_test_dhcp_dhclient_OBJECTS = test-dhcp-dhclient.$(OBJEXT) +am_test_dhcp_dhclient_OBJECTS = nm-dhcp-dhclient-utils.$(OBJEXT) \ + nm-dhcp-utils.$(OBJEXT) test-dhcp-dhclient.$(OBJEXT) test_dhcp_dhclient_OBJECTS = $(am_test_dhcp_dhclient_OBJECTS) test_dhcp_dhclient_DEPENDENCIES = \ $(top_builddir)/src/libNetworkManager.la @@ -112,6 +113,10 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +am_test_dhcp_utils_OBJECTS = test-dhcp-utils.$(OBJEXT) +test_dhcp_utils_OBJECTS = $(am_test_dhcp_utils_OBJECTS) +test_dhcp_utils_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -146,8 +151,9 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(test_dhcp_dhclient_SOURCES) -DIST_SOURCES = $(test_dhcp_dhclient_SOURCES) +SOURCES = $(test_dhcp_dhclient_SOURCES) $(test_dhcp_utils_SOURCES) +DIST_SOURCES = $(test_dhcp_dhclient_SOURCES) \ + $(test_dhcp_utils_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -204,6 +210,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -327,6 +335,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -346,6 +355,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -372,7 +382,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -453,25 +463,37 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I$(top_srcdir)/src/dhcp-manager \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/platform \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ -DTESTDIR="\"$(abs_srcdir)\"" -####### policy /etc/hosts test ####### +####### dhclient leases test ####### test_dhcp_dhclient_SOURCES = \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.h \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.h \ + $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c \ test-dhcp-dhclient.c test_dhcp_dhclient_LDADD = \ $(top_builddir)/src/libNetworkManager.la + +####### DHCP utils test ####### +test_dhcp_utils_SOURCES = \ + test-dhcp-utils.c + +test_dhcp_utils_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + EXTRA_DIST = \ test-dhclient-duid.leases \ test-dhclient-commented-duid.leases \ @@ -528,13 +550,20 @@ test-dhcp-dhclient$(EXEEXT): $(test_dhcp_dhclient_OBJECTS) $(test_dhcp_dhclient_ @rm -f test-dhcp-dhclient$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dhcp_dhclient_OBJECTS) $(test_dhcp_dhclient_LDADD) $(LIBS) +test-dhcp-utils$(EXEEXT): $(test_dhcp_utils_OBJECTS) $(test_dhcp_utils_DEPENDENCIES) $(EXTRA_test_dhcp_utils_DEPENDENCIES) + @rm -f test-dhcp-utils$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_dhcp_utils_OBJECTS) $(test_dhcp_utils_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-dhclient-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-dhcp-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dhcp-dhclient.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dhcp-utils.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -557,6 +586,34 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +nm-dhcp-dhclient-utils.o: $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.o -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.o `test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.o `test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c' || echo '$(srcdir)/'`$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c + +nm-dhcp-dhclient-utils.obj: $(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-dhclient-utils.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo -c -o nm-dhcp-dhclient-utils.obj `if test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-dhclient-utils.Tpo $(DEPDIR)/nm-dhcp-dhclient-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c' object='nm-dhcp-dhclient-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-dhclient-utils.obj `if test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; then $(CYGPATH_W) '$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/dhcp-manager/nm-dhcp-dhclient-utils.c'; fi` + +nm-dhcp-utils.o: $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-utils.o -MD -MP -MF $(DEPDIR)/nm-dhcp-utils.Tpo -c -o nm-dhcp-utils.o `test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c' || echo '$(srcdir)/'`$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-utils.Tpo $(DEPDIR)/nm-dhcp-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c' object='nm-dhcp-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-utils.o `test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c' || echo '$(srcdir)/'`$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c + +nm-dhcp-utils.obj: $(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm-dhcp-utils.obj -MD -MP -MF $(DEPDIR)/nm-dhcp-utils.Tpo -c -o nm-dhcp-utils.obj `if test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; then $(CYGPATH_W) '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm-dhcp-utils.Tpo $(DEPDIR)/nm-dhcp-utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c' object='nm-dhcp-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nm-dhcp-utils.obj `if test -f '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; then $(CYGPATH_W) '$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/dhcp-manager/nm-dhcp-utils.c'; fi` + mostlyclean-libtool: -rm -f *.lo diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 1ab182a7..4f7e96af 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -18,33 +18,50 @@ * */ +#include "config.h" + #include #include #include +#include +#include "gsystem-local-alloc.h" +#include "NetworkManagerUtils.h" #include "nm-dhcp-dhclient-utils.h" +#include "nm-dhcp-utils.h" #include "nm-utils.h" #include "nm-ip4-config.h" +#include "nm-platform.h" +#include "nm-utils-internal.h" -#define DEBUG 0 +#define DEBUG 1 static void test_config (const char *orig, const char *expected, const char *hostname, const char *dhcp_client_id, + GBytes *expected_new_client_id, const char *iface, - GByteArray *anycast_addr) + const char *anycast_addr) { - char *new; + gs_free char *new = NULL; + gs_unref_bytes GBytes *client_id = NULL; + gs_unref_bytes GBytes *new_client_id = NULL; + + if (dhcp_client_id) { + client_id = nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id); + g_assert (client_id); + } new = nm_dhcp_dhclient_create_config (iface, FALSE, - dhcp_client_id, + client_id, anycast_addr, hostname, "/path/to/dhclient.conf", - orig); + orig, + &new_client_id); g_assert (new != NULL); #if DEBUG @@ -58,9 +75,13 @@ test_config (const char *orig, new, expected); } #endif - g_assert (strlen (new) == strlen (expected)); - g_assert (strcmp (new, expected) == 0); - g_free (new); + g_assert_cmpstr (new, ==, expected); + + if (expected_new_client_id) { + g_assert (new_client_id); + g_assert (g_bytes_equal (new_client_id, expected_new_client_id)); + } else + g_assert (new_client_id == NULL); } /*******************************************/ @@ -82,11 +103,7 @@ static const char *orig_missing_expected = \ static void test_orig_missing (void) { - test_config (NULL, orig_missing_expected, - NULL, - NULL, - "eth0", - NULL); + test_config (NULL, orig_missing_expected, NULL, NULL, NULL, "eth0", NULL); } /*******************************************/ @@ -117,6 +134,7 @@ test_override_client_id (void) test_config (override_client_id_orig, override_client_id_expected, NULL, "11:22:33:44:55:66", + NULL, "eth0", NULL); } @@ -145,6 +163,7 @@ test_quote_client_id (void) test_config (NULL, quote_client_id_expected, NULL, "1234", + NULL, "eth0", NULL); } @@ -173,6 +192,113 @@ test_ascii_client_id (void) test_config (NULL, ascii_client_id_expected, NULL, "qb:cd:ef:12:34:56", + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *hex_single_client_id_expected = \ + "# Created by NetworkManager\n" + "\n" + "send dhcp-client-identifier ab:cd:0e:12:34:56; # added by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_hex_single_client_id (void) +{ + test_config (NULL, hex_single_client_id_expected, + NULL, + "ab:cd:e:12:34:56", + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *existing_hex_client_id_orig = \ + "send dhcp-client-identifier 00:30:04:20:7A:08;\n"; + +static const char *existing_hex_client_id_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "send dhcp-client-identifier 00:30:04:20:7A:08;\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_existing_hex_client_id (void) +{ + gs_unref_bytes GBytes *new_client_id = NULL; + const guint8 bytes[] = { 0x00, 0x30, 0x04,0x20, 0x7A, 0x08 }; + + new_client_id = g_bytes_new (bytes, sizeof (bytes)); + test_config (existing_hex_client_id_orig, existing_hex_client_id_expected, + NULL, + NULL, + new_client_id, + "eth0", + NULL); +} + +/*******************************************/ + +#define EACID "qb:cd:ef:12:34:56" + +static const char *existing_ascii_client_id_orig = \ + "send dhcp-client-identifier \"" EACID "\";\n"; + +static const char *existing_ascii_client_id_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "send dhcp-client-identifier \"" EACID "\";\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_existing_ascii_client_id (void) +{ + gs_unref_bytes GBytes *new_client_id = NULL; + char buf[STRLEN (EACID) + 1] = { 0 }; + + memcpy (buf + 1, EACID, STRLEN (EACID)); + new_client_id = g_bytes_new (buf, sizeof (buf)); + test_config (existing_ascii_client_id_orig, existing_ascii_client_id_expected, + NULL, + NULL, + new_client_id, "eth0", NULL); } @@ -205,6 +331,7 @@ test_override_hostname (void) test_config (override_hostname_orig, override_hostname_expected, "blahblah", NULL, + NULL, "eth0", NULL); } @@ -237,6 +364,7 @@ static void test_existing_alsoreq (void) { test_config (existing_alsoreq_orig, existing_alsoreq_expected, + NULL, NULL, NULL, "eth0", @@ -275,6 +403,7 @@ static void test_existing_multiline_alsoreq (void) { test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected, + NULL, NULL, NULL, "eth0", @@ -585,6 +714,9 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/override_client_id", test_override_client_id); g_test_add_func ("/dhcp/dhclient/quote_client_id", test_quote_client_id); g_test_add_func ("/dhcp/dhclient/ascii_client_id", test_ascii_client_id); + g_test_add_func ("/dhcp/dhclient/hex_single_client_id", test_hex_single_client_id); + g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id); + g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id); g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname); g_test_add_func ("/dhcp/dhclient/existing_alsoreq", test_existing_alsoreq); g_test_add_func ("/dhcp/dhclient/existing_multiline_alsoreq", test_existing_multiline_alsoreq); diff --git a/src/dhcp-manager/tests/test-dhcp-utils.c b/src/dhcp-manager/tests/test-dhcp-utils.c new file mode 100644 index 00000000..4ff8caad --- /dev/null +++ b/src/dhcp-manager/tests/test-dhcp-utils.c @@ -0,0 +1,723 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 - 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include "nm-dhcp-utils.h" +#include "nm-logging.h" +#include "nm-platform.h" + +#include "nm-test-utils.h" + +typedef struct { + const char *name; + const char *value; +} Option; + +static GHashTable * +fill_table (const Option *test_options, GHashTable *table) +{ + const Option *opt; + + if (!table) + table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + for (opt = test_options; opt->name; opt++) + g_hash_table_insert (table, (gpointer) opt->name, (gpointer) opt->value); + return table; +} + +static const Option generic_options[] = { + { "subnet_mask", "255.255.255.0" }, + { "ip_address", "192.168.1.106" }, + { "network_number", "192.168.1.0" }, + { "expiry", "1232324877" }, + { "dhcp_lease_time", "3600" }, + { "dhcp_server_identifier", "192.168.1.1" }, + { "routers", "192.168.1.1" }, + { "domain_name_servers", "216.254.95.2 216.231.41.2" }, + { "dhcp_message_type", "5" }, + { "broadcast_address", "192.168.1.255" }, + { "domain_search", "foobar.com blah.foobar.com" }, + { "host_name", "nmreallywhipsthe" }, + { "domain_name", "lamasass.com" }, + { "interface_mtu", "987" }, + { "static_routes", "10.1.1.5 10.1.1.1 100.99.88.56 10.1.1.1" }, + { NULL, NULL } +}; + +static void +test_generic_options (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const NMPlatformIP4Address *address; + const NMPlatformIP4Route *route; + guint32 tmp; + const char *expected_addr = "192.168.1.106"; + const char *expected_gw = "192.168.1.1"; + const char *expected_dns1 = "216.254.95.2"; + const char *expected_dns2 = "216.231.41.2"; + const char *expected_search1 = "foobar.com"; + const char *expected_search2 = "blah.foobar.com"; + const char *expected_route1_dest = "10.1.1.5"; + const char *expected_route1_gw = "10.1.1.1"; + const char *expected_route2_dest = "100.99.88.56"; + const char *expected_route2_gw = "10.1.1.1"; + + options = fill_table (generic_options, NULL); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); + address = nm_ip4_config_get_address (ip4_config, 0); + g_assert (inet_pton (AF_INET, expected_addr, &tmp) > 0); + g_assert (address->address == tmp); + g_assert (address->peer_address == 0); + g_assert_cmpint (address->plen, ==, 24); + + /* Gateway */ + g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0); + g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp); + + g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 0); + + g_assert_cmpint (nm_ip4_config_get_mtu (ip4_config), ==, 987); + + /* Domain searches */ + g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 2); + g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 0), ==, expected_search1); + g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 1), ==, expected_search2); + + /* DNS servers */ + g_assert_cmpint (nm_ip4_config_get_num_nameservers (ip4_config), ==, 2); + g_assert (inet_pton (AF_INET, expected_dns1, &tmp) > 0); + g_assert (nm_ip4_config_get_nameserver (ip4_config, 0) == tmp); + g_assert (inet_pton (AF_INET, expected_dns2, &tmp) > 0); + g_assert (nm_ip4_config_get_nameserver (ip4_config, 1) == tmp); + + /* Routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + + /* Route #1 */ + route = nm_ip4_config_get_route (ip4_config, 0); + g_assert (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0); + g_assert (route->network == tmp); + g_assert (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0); + g_assert (route->gateway == tmp); + g_assert_cmpint (route->plen, ==, 32); + g_assert_cmpint (route->metric, ==, 0); + + /* Route #2 */ + route = nm_ip4_config_get_route (ip4_config, 1); + g_assert (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0); + g_assert (route->network == tmp); + g_assert (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0); + g_assert (route->gateway == tmp); + g_assert_cmpint (route->plen, ==, 32); + g_assert_cmpint (route->metric, ==, 0); + + g_hash_table_destroy (options); +} + +static void +test_wins_options (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const NMPlatformIP4Address *address; + guint32 tmp; + const char *expected_wins1 = "63.12.199.5"; + const char *expected_wins2 = "150.4.88.120"; + static const Option data[] = { + { "netbios_name_servers", "63.12.199.5 150.4.88.120" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 address */ + g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); + address = nm_ip4_config_get_address (ip4_config, 0); + g_assert (address); + g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 2); + g_assert (inet_pton (AF_INET, expected_wins1, &tmp) > 0); + g_assert (nm_ip4_config_get_wins (ip4_config, 0) == tmp); + g_assert (inet_pton (AF_INET, expected_wins2, &tmp) > 0); + g_assert (nm_ip4_config_get_wins (ip4_config, 1) == tmp); + + g_hash_table_destroy (options); +} + +static void +ip4_test_route (NMIP4Config *ip4_config, + guint route_num, + const char *expected_dest, + const char *expected_gw, + guint expected_prefix) +{ + const NMPlatformIP4Route *route; + guint32 tmp; + + route = nm_ip4_config_get_route (ip4_config, route_num); + g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0); + g_assert (route->network == tmp); + g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0); + g_assert (route->gateway == tmp); + g_assert_cmpint (route->plen, ==, expected_prefix); + g_assert_cmpint (route->metric, ==, 0); +} + +static void +ip4_test_gateway (NMIP4Config *ip4_config, const char *expected_gw) +{ + guint32 tmp; + + g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); + g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0); + g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp); +} + +static void +test_classless_static_routes_1 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + const char *expected_route2_dest = "10.0.0.0"; + const char *expected_route2_gw = "10.17.66.41"; + static const Option data[] = { + /* dhclient custom format */ + { "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8); + + g_hash_table_destroy (options); +} + +static void +test_classless_static_routes_2 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + const char *expected_route2_dest = "10.0.0.0"; + const char *expected_route2_gw = "10.17.66.41"; + static const Option data[] = { + /* dhcpcd format */ + { "classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8); + + g_hash_table_destroy (options); +} + +static void +test_fedora_dhclient_classless_static_routes (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "129.210.177.128"; + const char *expected_route1_gw = "192.168.0.113"; + const char *expected_route2_dest = "2.0.0.0"; + const char *expected_route2_gw = "10.34.255.6"; + const char *expected_gateway = "192.168.0.113"; + static const Option data[] = { + /* Fedora dhclient format */ + { "classless_static_routes", "0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 25); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 7); + + /* Gateway */ + ip4_test_gateway (ip4_config, expected_gateway); + + g_hash_table_destroy (options); +} + +static void +test_dhclient_invalid_classless_routes_1 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + static const Option data[] = { + /* dhclient format */ + { "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*ignoring invalid classless static routes*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + + g_hash_table_destroy (options); +} + +static void +test_dhcpcd_invalid_classless_routes_1 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "10.1.1.5"; + const char *expected_route1_gw = "10.1.1.1"; + const char *expected_route2_dest = "100.99.88.56"; + const char *expected_route2_gw = "10.1.1.1"; + static const Option data[] = { + /* dhcpcd format */ + { "classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*ignoring invalid classless static routes*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* Test falling back to old-style static routes if the classless static + * routes are invalid. + */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32); + + g_hash_table_destroy (options); +} + +static void +test_dhclient_invalid_classless_routes_2 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "10.1.1.5"; + const char *expected_route1_gw = "10.1.1.1"; + const char *expected_route2_dest = "100.99.88.56"; + const char *expected_route2_gw = "10.1.1.1"; + static const Option data[] = { + { "rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*ignoring invalid classless static routes*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* Test falling back to old-style static routes if the classless static + * routes are invalid. + */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32); + + g_hash_table_destroy (options); +} + +static void +test_dhcpcd_invalid_classless_routes_2 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "10.1.1.5"; + const char *expected_route1_gw = "10.1.1.1"; + const char *expected_route2_dest = "100.99.88.56"; + const char *expected_route2_gw = "10.1.1.1"; + static const Option data[] = { + { "classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*ignoring invalid classless static routes*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* Test falling back to old-style static routes if the classless static + * routes are invalid. + */ + + /* Routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32); + ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32); + + g_hash_table_destroy (options); +} + +static void +test_dhclient_invalid_classless_routes_3 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + static const Option data[] = { + { "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*ignoring invalid classless static routes*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + + g_hash_table_destroy (options); +} + +static void +test_dhcpcd_invalid_classless_routes_3 (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + static Option data[] = { + { "classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*DHCP provided invalid classless static route*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + + g_hash_table_destroy (options); +} + +static void +test_dhclient_gw_in_classless_routes (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + const char *expected_gateway = "192.2.3.4"; + static Option data[] = { + { "rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + + /* Gateway */ + ip4_test_gateway (ip4_config, expected_gateway); + + g_hash_table_destroy (options); +} + +static void +test_dhcpcd_gw_in_classless_routes (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_route1_dest = "192.168.10.0"; + const char *expected_route1_gw = "192.168.1.1"; + const char *expected_gateway = "192.2.3.4"; + static Option data[] = { + { "classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* IP4 routes */ + g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1); + ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24); + + /* Gateway */ + ip4_test_gateway (ip4_config, expected_gateway); + + g_hash_table_destroy (options); +} + +static void +test_escaped_domain_searches (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const char *expected_search0 = "host1"; + const char *expected_search1 = "host2"; + const char *expected_search2 = "host3"; + static const Option data[] = { + { "domain_search", "host1\\032host2\\032host3" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + /* domain searches */ + g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 3); + g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 0), ==, expected_search0); + g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 1), ==, expected_search1); + g_assert_cmpstr (nm_ip4_config_get_search (ip4_config, 2), ==, expected_search2); + + g_hash_table_destroy (options); +} + +static void +test_invalid_escaped_domain_searches (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + static const Option data[] = { + { "domain_search", "host1\\aahost2\\032host3" }, + { NULL, NULL } + }; + + options = fill_table (generic_options, NULL); + options = fill_table (data, options); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*invalid domain search*"); + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + g_test_assert_expected_messages (); + + /* domain searches */ + g_assert_cmpint (nm_ip4_config_get_num_searches (ip4_config), ==, 0); + + g_hash_table_destroy (options); +} + +static void +test_ip4_missing_prefix (const char *ip, guint32 expected_prefix) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const NMPlatformIP4Address *address; + + options = fill_table (generic_options, NULL); + g_hash_table_insert (options, "ip_address", (gpointer) ip); + g_hash_table_remove (options, "subnet_mask"); + + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); + address = nm_ip4_config_get_address (ip4_config, 0); + g_assert (address); + g_assert_cmpint (address->plen, ==, expected_prefix); + + g_hash_table_destroy (options); +} + +static void +test_ip4_missing_prefix_24 (void) +{ + test_ip4_missing_prefix ("192.168.1.10", 24); +} + +static void +test_ip4_missing_prefix_16 (void) +{ + test_ip4_missing_prefix ("172.16.54.50", 16); +} + +static void +test_ip4_missing_prefix_8 (void) +{ + test_ip4_missing_prefix ("10.1.2.3", 8); +} + +static void +test_ip4_prefix_classless (void) +{ + GHashTable *options; + NMIP4Config *ip4_config; + const NMPlatformIP4Address *address; + + /* Ensure that the missing-subnet-mask handler doesn't mangle classless + * subnet masks at all. The handler should trigger only if the server + * doesn't send the subnet mask. + */ + + options = fill_table (generic_options, NULL); + g_hash_table_insert (options, "ip_address", "172.16.54.22"); + g_hash_table_insert (options, "subnet_mask", "255.255.252.0"); + + ip4_config = nm_dhcp_utils_ip4_config_from_options ("eth0", options, 0); + g_assert (ip4_config); + + g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); + address = nm_ip4_config_get_address (ip4_config, 0); + g_assert (address); + g_assert_cmpint (address->plen, ==, 22); + + g_hash_table_destroy (options); +} + +#define COMPARE_ID(src, is_str, expected, expected_len) \ +G_STMT_START { \ + gs_unref_bytes GBytes *b = NULL; \ + const char *p; \ + gsize l; \ + \ + b = nm_dhcp_utils_client_id_string_to_bytes (src); \ + g_assert (b); \ + p = g_bytes_get_data (b, &l); \ + if (is_str) { \ + g_assert_cmpint (l, ==, expected_len + 1); \ + g_assert_cmpint (((const char *) p)[0], ==, 0); \ + g_assert (memcmp (p + 1, expected, expected_len) == 0); \ + } else { \ + g_assert_cmpint (l, ==, expected_len); \ + g_assert (memcmp (p, expected, expected_len) == 0); \ + } \ +} G_STMT_END + +static void +test_client_id_from_string (void) +{ + const char *nothex = "asdfasdfasdfasdfasdfasdfasdf"; + const char *allhex = "00:11:22:33:4:55:66:77:88"; + const guint8 allhex_bin[] = { 0x00, 0x11, 0x22, 0x33, 0x04, 0x55, 0x66, 0x77, 0x88 }; + const char *somehex = "00:11:22:33:44:55:asdfasdfasdf:99:10"; + const char *nocolons = "0011223344559910"; + const char *endcolon = "00:11:22:33:44:55:"; + + COMPARE_ID (nothex, TRUE, nothex, strlen (nothex)); + COMPARE_ID (allhex, FALSE, allhex_bin, sizeof (allhex_bin)); + COMPARE_ID (somehex, TRUE, somehex, strlen (somehex)); + COMPARE_ID (nocolons, TRUE, nocolons, strlen (nocolons)); + COMPARE_ID (endcolon, TRUE, endcolon, strlen (endcolon)); +} + +NMTST_DEFINE (); + +int main (int argc, char **argv) +{ + nmtst_init_assert_logging (&argc, &argv); + nm_logging_setup ("WARN", "DEFAULT", NULL, NULL); + + g_test_add_func ("/dhcp/generic-options", test_generic_options); + g_test_add_func ("/dhcp/wins-options", test_wins_options); + g_test_add_func ("/dhcp/classless-static-routes-1", test_classless_static_routes_1); + g_test_add_func ("/dhcp/classless-static-routes-2", test_classless_static_routes_2); + g_test_add_func ("/dhcp/fedora-dhclient-classless-static-routes", test_fedora_dhclient_classless_static_routes); + g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-1", test_dhclient_invalid_classless_routes_1); + g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-1", test_dhcpcd_invalid_classless_routes_1); + g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-2", test_dhclient_invalid_classless_routes_2); + g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-2", test_dhcpcd_invalid_classless_routes_2); + g_test_add_func ("/dhcp/dhclient-invalid-classless-routes-3", test_dhclient_invalid_classless_routes_3); + g_test_add_func ("/dhcp/dhcpcd-invalid-classless-routes-3", test_dhcpcd_invalid_classless_routes_3); + g_test_add_func ("/dhcp/dhclient-gw-in-classless-routes", test_dhclient_gw_in_classless_routes); + g_test_add_func ("/dhcp/dhcpcd-gw-in-classless-routes", test_dhcpcd_gw_in_classless_routes); + g_test_add_func ("/dhcp/escaped-domain-searches", test_escaped_domain_searches); + g_test_add_func ("/dhcp/invalid-escaped-domain-searches", test_invalid_escaped_domain_searches); + g_test_add_func ("/dhcp/ip4-missing-prefix-24", test_ip4_missing_prefix_24); + g_test_add_func ("/dhcp/ip4-missing-prefix-16", test_ip4_missing_prefix_16); + g_test_add_func ("/dhcp/ip4-missing-prefix-8", test_ip4_missing_prefix_8); + g_test_add_func ("/dhcp/ip4-prefix-classless", test_ip4_prefix_classless); + g_test_add_func ("/dhcp/client-id-from-string", test_client_id_from_string); + + return g_test_run (); +} + diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c index 8367693d..f26ccfaa 100644 --- a/src/dns-manager/nm-dns-dnsmasq.c +++ b/src/dns-manager/nm-dns-dnsmasq.c @@ -18,7 +18,8 @@ * */ -#include +#include "config.h" + #include #include #include @@ -35,6 +36,7 @@ #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "nm-dns-utils.h" +#include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMDnsDnsmasq, nm_dns_dnsmasq, NM_TYPE_DNS_PLUGIN) @@ -50,26 +52,6 @@ typedef struct { /*******************************************/ -static inline const char * -find_dnsmasq (void) -{ - static const char *paths[] = { - DNSMASQ_PATH, - "/usr/local/sbin/dnsmasq", - "/usr/sbin/dnsmasq", - "/sbin/dnsmasq", - NULL - }; - const char **binary = paths; - - while (*binary != NULL) { - if (**binary && g_file_test (*binary, G_FILE_TEST_EXISTS)) - return *binary; - binary++; - } - return NULL; -} - static gboolean add_ip4_config (GString *str, NMIP4Config *ip4, gboolean split) { @@ -225,6 +207,7 @@ update (NMDnsPlugin *plugin, const char *hostname) { NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin); + const char *dm_binary; GString *conf; GSList *iter; const char *argv[15]; @@ -240,6 +223,12 @@ update (NMDnsPlugin *plugin, */ nm_dns_plugin_child_kill (plugin); + dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, NULL); + if (!dm_binary) { + nm_log_warn (LOGD_DNS, "Could not find dnsmasq binary"); + return FALSE; + } + /* Build up the new dnsmasq config file */ conf = g_string_sized_new (150); @@ -281,7 +270,7 @@ update (NMDnsPlugin *plugin, nm_log_dbg (LOGD_DNS, "dnsmasq local caching DNS configuration:"); nm_log_dbg (LOGD_DNS, "%s", conf->str); - argv[idx++] = find_dnsmasq (); + argv[idx++] = dm_binary; argv[idx++] = "--no-resolv"; /* Use only commandline */ argv[idx++] = "--keep-in-foreground"; argv[idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */ diff --git a/src/dns-manager/nm-dns-dnsmasq.h b/src/dns-manager/nm-dns-dnsmasq.h index 70933c0f..fc80f079 100644 --- a/src/dns-manager/nm-dns-dnsmasq.h +++ b/src/dns-manager/nm-dns-dnsmasq.h @@ -16,8 +16,8 @@ * Copyright (C) 2010 Red Hat, Inc. */ -#ifndef NM_DNS_DNSMASQ_H -#define NM_DNS_DNSMASQ_H +#ifndef __NETWORKMANAGER_DNS_DNSMASQ_H__ +#define __NETWORKMANAGER_DNS_DNSMASQ_H__ #include #include @@ -43,5 +43,5 @@ GType nm_dns_dnsmasq_get_type (void); NMDnsPlugin *nm_dns_dnsmasq_new (void); -#endif /* NM_DNS_DNSMASQ_H */ +#endif /* __NETWORKMANAGER_DNS_DNSMASQ_H__ */ diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 466aa9a8..0d93d8bb 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -35,6 +35,7 @@ #include #include +#include "nm-utils.h" #include "nm-dns-manager.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" @@ -47,7 +48,7 @@ #include "nm-dns-dnsmasq.h" #include "nm-dns-unbound.h" -#if HAVE_LIBSOUP +#if WITH_LIBSOUP #include #ifdef SOUP_CHECK_VERSION @@ -130,12 +131,8 @@ merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src) num = nm_ip4_config_get_num_nameservers (src); for (i = 0; i < num; i++) { - guint32 addr; - char buf[INET_ADDRSTRLEN]; - - addr = nm_ip4_config_get_nameserver (src, i); - if (inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN) > 0) - add_string_item (rc->nameservers, buf); + add_string_item (rc->nameservers, + nm_utils_inet4_ntop (nm_ip4_config_get_nameserver (src, i), NULL)); } num = nm_ip4_config_get_num_domains (src); @@ -161,12 +158,8 @@ merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src) /* NIS stuff */ num = nm_ip4_config_get_num_nis_servers (src); for (i = 0; i < num; i++) { - guint32 addr; - char buf[INET_ADDRSTRLEN]; - - addr = nm_ip4_config_get_nis_server (src, i); - if (inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN) > 0) - add_string_item (rc->nis_servers, buf); + add_string_item (rc->nis_servers, + nm_utils_inet4_ntop (nm_ip4_config_get_nis_server (src, i), NULL)); } if (nm_ip4_config_get_nis_domain (src)) { @@ -187,25 +180,21 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src) num = nm_ip6_config_get_num_nameservers (src); for (i = 0; i < num; i++) { const struct in6_addr *addr; - char buf[INET6_ADDRSTRLEN]; - char *tmp; + char buf[NM_UTILS_INET_ADDRSTRLEN + 50]; addr = nm_ip6_config_get_nameserver (src, i); /* inet_ntop is probably supposed to do this for us, but it doesn't */ - if (IN6_IS_ADDR_V4MAPPED (addr)) { - if (inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, INET_ADDRSTRLEN) > 0) - add_string_item (rc->nameservers, buf); - } else { - if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) { - if (iface && IN6_IS_ADDR_LINKLOCAL (addr)) { - tmp = g_strdup_printf ("%s%%%s", buf, iface); - add_string_item (rc->nameservers, tmp); - g_free (tmp); - } else - add_string_item (rc->nameservers, buf); + if (IN6_IS_ADDR_V4MAPPED (addr)) + nm_utils_inet4_ntop (addr->s6_addr32[3], buf); + else { + nm_utils_inet6_ntop (addr, buf); + if (iface && IN6_IS_ADDR_LINKLOCAL (addr)) { + g_strlcat (buf, "%", sizeof (buf)); + g_strlcat (buf, iface, sizeof (buf)); } } + add_string_item (rc->nameservers, buf); } num = nm_ip6_config_get_num_domains (src); @@ -359,8 +348,8 @@ write_resolv_conf (FILE *f, if (fprintf (f, "%s","# Generated by NetworkManager\n") < 0) { g_set_error (error, - NM_DNS_MANAGER_ERROR, - NM_DNS_MANAGER_ERROR_SYSTEM, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not write " _PATH_RESCONF ": %s\n", g_strerror (errno)); return FALSE; @@ -425,8 +414,8 @@ dispatch_resolvconf (char **searches, nm_log_info (LOGD_DNS, "Writing DNS information to %s", RESOLVCONF_PATH); if ((f = popen (cmd, "w")) == NULL) g_set_error (error, - NM_DNS_MANAGER_ERROR, - NM_DNS_MANAGER_ERROR_SYSTEM, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not write to %s: %s\n", RESOLVCONF_PATH, g_strerror (errno)); @@ -481,8 +470,8 @@ update_resolv_conf (char **searches, old_errno = errno; if ((f = fopen (_PATH_RESCONF, "w")) == NULL) { g_set_error (error, - NM_DNS_MANAGER_ERROR, - NM_DNS_MANAGER_ERROR_SYSTEM, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not open %s: %s\nCould not open %s: %s\n", tmp_resolv_conf_realpath, g_strerror (old_errno), @@ -504,8 +493,8 @@ update_resolv_conf (char **searches, * since its error is more important. */ g_set_error (error, - NM_DNS_MANAGER_ERROR, - NM_DNS_MANAGER_ERROR_SYSTEM, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not close %s: %s\n", tmp_resolv_conf_realpath, g_strerror (errno)); @@ -518,8 +507,8 @@ update_resolv_conf (char **searches, if (*error == NULL && do_rename) { if (rename (tmp_resolv_conf_realpath, resolv_conf_realpath) < 0) { g_set_error (error, - NM_DNS_MANAGER_ERROR, - NM_DNS_MANAGER_ERROR_SYSTEM, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not replace " _PATH_RESCONF ": %s\n", g_strerror (errno)); } @@ -972,8 +961,7 @@ nm_dns_manager_set_hostname (NMDnsManager *mgr, /* Certain hostnames we don't want to include in resolv.conf 'searches' */ if ( hostname - && strcmp (hostname, "localhost.localdomain") - && strcmp (hostname, "localhost6.localdomain6") + && nm_utils_is_specific_hostname (hostname) && !strstr (hostname, ".in-addr.arpa") && strchr (hostname, '.')) { filtered = hostname; @@ -1067,16 +1055,6 @@ nm_dns_manager_get (void) return singleton; } -GQuark -nm_dns_manager_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm_dns_manager_error"); - - return quark; -} - static void init_resolv_conf_mode (NMDnsManager *self) { diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h index b2bf2467..bc374fcf 100644 --- a/src/dns-manager/nm-dns-manager.h +++ b/src/dns-manager/nm-dns-manager.h @@ -21,30 +21,19 @@ * and others */ -#ifndef NM_DNS_MANAGER_H -#define NM_DNS_MANAGER_H +#ifndef __NETWORKMANAGER_DNS_MANAGER_H__ +#define __NETWORKMANAGER_DNS_MANAGER_H__ #include -#include #include "nm-ip4-config.h" #include "nm-ip6-config.h" -typedef enum { - NM_DNS_MANAGER_ERROR_SYSTEM, - NM_DNS_MANAGER_ERROR_INVALID_NAMESERVER, - NM_DNS_MANAGER_ERROR_INVALID_HOST, - NM_DNS_MANAGER_ERROR_INVALID_ID -} NMDnsManagerError; - typedef enum { NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0, NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, NM_DNS_IP_CONFIG_TYPE_VPN } NMDnsIPConfigType; -#define NM_DNS_MANAGER_ERROR nm_dns_manager_error_quark () -GQuark nm_dns_manager_error_quark (void); - G_BEGIN_DECLS #define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ()) @@ -114,4 +103,4 @@ NMDnsManagerResolvConfMode nm_dns_manager_get_resolv_conf_mode (NMDnsManager *mg G_END_DECLS -#endif /* NM_DNS_MANAGER_H */ +#endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c index e85b2a09..b083b105 100644 --- a/src/dns-manager/nm-dns-plugin.c +++ b/src/dns-manager/nm-dns-plugin.c @@ -17,7 +17,8 @@ * */ -#include +#include "config.h" + #include #include #include @@ -28,6 +29,7 @@ #include "nm-dns-plugin.h" #include "nm-logging.h" #include "nm-posix-signals.h" +#include "NetworkManagerUtils.h" typedef struct { gboolean disposed; @@ -196,29 +198,6 @@ nm_dns_plugin_child_spawn (NMDnsPlugin *self, return priv->pid; } -typedef struct { - int pid; - char *progname; -} KillInfo; - -static gboolean -ensure_killed (gpointer data) -{ - KillInfo *info = data; - - if (kill (info->pid, 0) == 0) - kill (info->pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_DNS, "waiting for %s pid %d to exit", info->progname, info->pid); - waitpid (info->pid, NULL, 0); - nm_log_dbg (LOGD_DNS, "dnsmasq pid %d cleaned up", info->pid); - - g_free (info->progname); - g_free (info); - return FALSE; -} - gboolean nm_dns_plugin_child_kill (NMDnsPlugin *self) { NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self); @@ -229,21 +208,7 @@ gboolean nm_dns_plugin_child_kill (NMDnsPlugin *self) } if (priv->pid) { - KillInfo *info; - - if (kill (priv->pid, SIGTERM) == 0) { - info = g_malloc0 (sizeof (KillInfo)); - info->pid = priv->pid; - info->progname = g_strdup (priv->progname); - g_timeout_add_seconds (2, ensure_killed, info); - } else { - kill (priv->pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_DNS, "waiting for %s pid %d to exit", priv->progname, priv->pid); - waitpid (priv->pid, NULL, 0); - nm_log_dbg (LOGD_DNS, "%s pid %d cleaned up", priv->progname, priv->pid); - } + nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_DNS, priv->progname, 2000, NULL, NULL); priv->pid = 0; g_free (priv->progname); priv->progname = NULL; diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h index 41a12a58..ee735a5a 100644 --- a/src/dns-manager/nm-dns-plugin.h +++ b/src/dns-manager/nm-dns-plugin.h @@ -16,8 +16,8 @@ * Copyright (C) 2010 Red Hat, Inc. */ -#ifndef NM_DNS_PLUGIN_H -#define NM_DNS_PLUGIN_H +#ifndef __NETWORKMANAGER_DNS_PLUGIN_H__ +#define __NETWORKMANAGER_DNS_PLUGIN_H__ #include #include @@ -109,5 +109,5 @@ GPid nm_dns_plugin_child_spawn (NMDnsPlugin *self, gboolean nm_dns_plugin_child_kill (NMDnsPlugin *self); -#endif /* NM_DNS_PLUGIN_H */ +#endif /* __NETWORKMANAGER_DNS_PLUGIN_H__ */ diff --git a/src/dns-manager/nm-dns-unbound.c b/src/dns-manager/nm-dns-unbound.c index 137fd20b..533290c1 100644 --- a/src/dns-manager/nm-dns-unbound.c +++ b/src/dns-manager/nm-dns-unbound.c @@ -17,6 +17,8 @@ * Copyright (C) 2014 Red Hat, Inc. * Author: Pavel Šimerda */ +#include "config.h" + #include "nm-dns-unbound.h" #include "NetworkManagerUtils.h" diff --git a/src/dns-manager/nm-dns-unbound.h b/src/dns-manager/nm-dns-unbound.h index 2aaae7dd..261326b2 100644 --- a/src/dns-manager/nm-dns-unbound.h +++ b/src/dns-manager/nm-dns-unbound.h @@ -15,8 +15,8 @@ * * Copyright (C) 2014 Red Hat, Inc. */ -#ifndef NM_DNS_UNBOUND_H -#define NM_DNS_UNBOUND_H +#ifndef __NETWORKMANAGER_DNS_UNBOUND_H__ +#define __NETWORKMANAGER_DNS_UNBOUND_H__ #include @@ -41,4 +41,4 @@ GType nm_dns_unbound_get_type (void); NMDnsPlugin *nm_dns_unbound_new (void); -#endif /* NM_DNS_UNBOUND_H */ +#endif /* __NETWORKMANAGER_DNS_UNBOUND_H__ */ diff --git a/src/dns-manager/nm-dns-utils.c b/src/dns-manager/nm-dns-utils.c index 3e564ace..4a5255a4 100644 --- a/src/dns-manager/nm-dns-utils.c +++ b/src/dns-manager/nm-dns-utils.c @@ -17,10 +17,13 @@ * */ +#include "config.h" + #include #include #include "nm-dns-utils.h" +#include "nm-platform.h" #include "nm-utils.h" static void diff --git a/src/dns-manager/nm-dns-utils.h b/src/dns-manager/nm-dns-utils.h index daa6711c..75c6b060 100644 --- a/src/dns-manager/nm-dns-utils.h +++ b/src/dns-manager/nm-dns-utils.h @@ -17,8 +17,8 @@ * */ -#ifndef NM_DNS_UTILS_H -#define NM_DNS_UTILS_H +#ifndef __NETWORKMANAGER_DNS_UTILS_H__ +#define __NETWORKMANAGER_DNS_UTILS_H__ #include "nm-ip4-config.h" diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.c b/src/dnsmasq-manager/nm-dnsmasq-manager.c index 21bbd23a..2f38ea71 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-manager.c +++ b/src/dnsmasq-manager/nm-dnsmasq-manager.c @@ -18,7 +18,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include @@ -33,6 +34,7 @@ #include "nm-glib-compat.h" #include "nm-posix-signals.h" #include "nm-utils.h" +#include "NetworkManagerUtils.h" typedef struct { char *iface; @@ -53,22 +55,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef enum { - NM_DNSMASQ_MANAGER_ERROR_NOT_FOUND, - NM_DNSMASQ_MANAGER_ERROR_INVALID_IP_RANGE, -} NMDnsMasqManagerError; - -GQuark -nm_dnsmasq_manager_error_quark (void) -{ - static GQuark quark; - - if (!quark) - quark = g_quark_from_static_string ("nm_dnsmasq_manager_error"); - - return quark; -} - static void nm_dnsmasq_manager_init (NMDnsMasqManager *manager) { @@ -168,27 +154,6 @@ nm_cmd_line_add_string (NMCmdLine *cmd, const char *str) /*******************************************/ -static inline const char * -nm_find_dnsmasq (void) -{ - static const char *dnsmasq_binary_paths[] = { - DNSMASQ_PATH, - "/usr/local/sbin/dnsmasq", - "/usr/sbin/dnsmasq", - "/sbin/dnsmasq", - NULL - }; - const char **dnsmasq_binary = dnsmasq_binary_paths; - - while (*dnsmasq_binary != NULL) { - if (**dnsmasq_binary && g_file_test (*dnsmasq_binary, G_FILE_TEST_EXISTS)) - break; - dnsmasq_binary++; - } - - return *dnsmasq_binary; -} - static void dm_exit_code (guint dm_exit_status) { @@ -249,7 +214,6 @@ create_dm_cmd_line (const char *iface, const char *pidfile, GError **error) { - const char *dm_binary; NMCmdLine *cmd; GString *s; const NMPlatformIP4Address *tmp; @@ -257,16 +221,11 @@ create_dm_cmd_line (const char *iface, char last[INET_ADDRSTRLEN]; char localaddr[INET_ADDRSTRLEN]; char *error_desc = NULL; + const char *dm_binary; - dm_binary = nm_find_dnsmasq (); - if (!dm_binary) { - g_set_error_literal (error, NM_DNSMASQ_MANAGER_ERROR, NM_DNSMASQ_MANAGER_ERROR_NOT_FOUND, - "Could not find dnsmasq binary."); + dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, error); + if (!dm_binary) return NULL; - } - - /* Find the IP4 address to use */ - tmp = nm_ip4_config_get_address (ip4_config, 0); /* Create dnsmasq command line */ cmd = nm_cmd_line_new (); @@ -297,6 +256,9 @@ create_dm_cmd_line (const char *iface, */ nm_cmd_line_add_string (cmd, "--strict-order"); + /* Find the IP4 address to use */ + tmp = nm_ip4_config_get_address (ip4_config, 0); + s = g_string_new ("--listen-address="); nm_utils_inet4_ntop (tmp->address, localaddr); g_string_append (s, localaddr); @@ -305,12 +267,13 @@ create_dm_cmd_line (const char *iface, if (!nm_dnsmasq_utils_get_range (tmp, first, last, &error_desc)) { g_set_error_literal (error, - NM_DNSMASQ_MANAGER_ERROR, - NM_DNSMASQ_MANAGER_ERROR_INVALID_IP_RANGE, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, error_desc); nm_log_warn (LOGD_SHARING, "Failed to find DHCP address ranges: %s", error_desc); g_free (error_desc); - goto error; + nm_cmd_line_destroy (cmd); + return NULL; } s = g_string_new ("--dhcp-range="); @@ -331,10 +294,6 @@ create_dm_cmd_line (const char *iface, g_string_free (s, TRUE); return cmd; - -error: - nm_cmd_line_destroy (cmd); - return NULL; } static void @@ -432,22 +391,6 @@ nm_dnsmasq_manager_start (NMDnsMasqManager *manager, return priv->pid > 0; } -static gboolean -ensure_killed (gpointer data) -{ - int pid = GPOINTER_TO_INT (data); - - if (kill (pid, 0) == 0) - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_SHARING, "waiting for dnsmasq pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_SHARING, "dnsmasq pid %d cleaned up", pid); - - return FALSE; -} - void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager) { @@ -463,17 +406,7 @@ nm_dnsmasq_manager_stop (NMDnsMasqManager *manager) } if (priv->pid) { - if (kill (priv->pid, SIGTERM) == 0) - g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid)); - else { - kill (priv->pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_SHARING, "waiting for dnsmasq pid %d to exit", priv->pid); - waitpid (priv->pid, NULL, 0); - nm_log_dbg (LOGD_SHARING, "dnsmasq pid %d cleaned up", priv->pid); - } - + nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_SHARING, "dnsmasq", 2000, NULL, NULL); priv->pid = 0; } diff --git a/src/dnsmasq-manager/nm-dnsmasq-manager.h b/src/dnsmasq-manager/nm-dnsmasq-manager.h index e98a6adb..257cc755 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-manager.h +++ b/src/dnsmasq-manager/nm-dnsmasq-manager.h @@ -18,8 +18,8 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#ifndef NM_DNSMASQ_MANAGER_H -#define NM_DNSMASQ_MANAGER_H +#ifndef __NETWORKMANAGER_DNSMASQ_MANAGER_H__ +#define __NETWORKMANAGER_DNSMASQ_MANAGER_H__ #include #include @@ -61,9 +61,4 @@ gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager); -#define NM_DNSMASQ_MANAGER_ERROR nm_dnsmasq_manager_error_quark() -#define NM_TYPE_DNSMASQ_MANAGER_ERROR (nm_dnsmasq_manager_error_get_type ()) - -GQuark nm_dnsmasq_manager_error_quark (void); - -#endif /* NM_DNSMASQ_MANAGER_H */ +#endif /* __NETWORKMANAGER_DNSMASQ_MANAGER_H__ */ diff --git a/src/dnsmasq-manager/nm-dnsmasq-utils.c b/src/dnsmasq-manager/nm-dnsmasq-utils.c index 7036b409..4394ae7b 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-utils.c +++ b/src/dnsmasq-manager/nm-dnsmasq-utils.c @@ -18,7 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#include +#include "config.h" + #include #include diff --git a/src/dnsmasq-manager/nm-dnsmasq-utils.h b/src/dnsmasq-manager/nm-dnsmasq-utils.h index 4534c6ef..bb468c82 100644 --- a/src/dnsmasq-manager/nm-dnsmasq-utils.h +++ b/src/dnsmasq-manager/nm-dnsmasq-utils.h @@ -18,8 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_DNSMASQ_UTILS_H -#define NM_DNSMASQ_UTILS_H +#ifndef __NETWORKMANAGER_DNSMASQ_UTILS_H__ +#define __NETWORKMANAGER_DNSMASQ_UTILS_H__ #include #include "nm-platform.h" @@ -29,4 +29,4 @@ gboolean nm_dnsmasq_utils_get_range (const NMPlatformIP4Address *addr, char *out_last, char **out_error_desc); -#endif /* NM_DNSMASQ_UTILS_H */ +#endif /* __NETWORKMANAGER_DNSMASQ_UTILS_H__ */ diff --git a/src/dnsmasq-manager/tests/Makefile.am b/src/dnsmasq-manager/tests/Makefile.am index 9c7f4ab5..c6ce1cda 100644 --- a/src/dnsmasq-manager/tests/Makefile.am +++ b/src/dnsmasq-manager/tests/Makefile.am @@ -1,12 +1,12 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I$(top_srcdir)/src/dnsmasq-manager \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/platform \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ -DTESTDIR="\"$(abs_srcdir)\"" diff --git a/src/dnsmasq-manager/tests/Makefile.in b/src/dnsmasq-manager/tests/Makefile.in index 52301e3d..d5f92416 100644 --- a/src/dnsmasq-manager/tests/Makefile.in +++ b/src/dnsmasq-manager/tests/Makefile.in @@ -204,6 +204,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -327,6 +329,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -346,6 +349,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -372,7 +376,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -453,13 +457,13 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I$(top_srcdir)/src/dnsmasq-manager \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/platform \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ -DTESTDIR="\"$(abs_srcdir)\"" diff --git a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c index 07dbc0f7..f8120ffe 100644 --- a/src/dnsmasq-manager/tests/test-dnsmasq-utils.c +++ b/src/dnsmasq-manager/tests/test-dnsmasq-utils.c @@ -18,6 +18,8 @@ * */ +#include "config.h" + #include #include diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c deleted file mode 100644 index c99372a1..00000000 --- a/src/firewall-manager/nm-firewall-manager.c +++ /dev/null @@ -1,360 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2011 Red Hat, Inc. - */ - -#include -#include -#include - -#include "nm-firewall-manager.h" -#include "nm-dbus-manager.h" -#include "nm-logging.h" - -#define NM_FIREWALL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_FIREWALL_MANAGER, \ - NMFirewallManagerPrivate)) - -G_DEFINE_TYPE (NMFirewallManager, nm_firewall_manager, G_TYPE_OBJECT) - -/* Properties */ -enum { - PROP_0 = 0, - PROP_AVAILABLE, - LAST_PROP -}; - -typedef struct { - NMDBusManager * dbus_mgr; - guint name_owner_id; - DBusGProxy * proxy; - gboolean running; -} NMFirewallManagerPrivate; - -enum { - STARTED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/********************************************************************/ - -typedef struct { - char *iface; - FwAddToZoneFunc callback; - gpointer user_data; - guint id; - gboolean completed; -} CBInfo; - -static void -cb_info_free (CBInfo *info) -{ - g_return_if_fail (info != NULL); - - if (!info->completed) - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call cancelled [%u]", info->iface, info->id); - - g_free (info->iface); - g_free (info); -} - -static CBInfo * -_cb_info_create (const char *iface, FwAddToZoneFunc callback, gpointer user_data) -{ - static guint id; - CBInfo *info; - - info = g_malloc (sizeof (CBInfo)); - if (++id == 0) - ++id; - info->id = id; - info->iface = g_strdup (iface); - info->completed = FALSE; - info->callback = callback; - info->user_data = user_data; - - return info; -} - -static void -add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - CBInfo *info = user_data; - GError *error = NULL; - char *zone = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - G_TYPE_STRING, &zone, - G_TYPE_INVALID)) { - g_assert (error); - if (g_strcmp0 (error->message, "ZONE_ALREADY_SET") != 0) { - nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", - info->iface, info->id, error->code, error->message); - } else { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", - info->iface, info->id, error->code, error->message); - } - } else { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change succeeded [%u]", - info->iface, info->id); - } - - info->callback (error, info->user_data); - - info->completed = TRUE; - g_free (zone); - g_clear_error (&error); -} - -gpointer -nm_firewall_manager_add_or_change_zone (NMFirewallManager *self, - const char *iface, - const char *zone, - gboolean add, /* TRUE == add, FALSE == change */ - FwAddToZoneFunc callback, - gpointer user_data) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - CBInfo *info; - - if (priv->running == FALSE) { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface); - callback (NULL, user_data); - return NULL; - } - - info = _cb_info_create (iface, callback, user_data); - - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u]", iface, add ? "add" : "change", - zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id); - return dbus_g_proxy_begin_call_with_timeout (priv->proxy, - add ? "addInterface" : "changeZone", - add_or_change_cb, - info, - (GDestroyNotify) cb_info_free, - 10000, /* timeout */ - G_TYPE_STRING, zone ? zone : "", - G_TYPE_STRING, iface, - G_TYPE_INVALID); -} - -static void -remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - CBInfo *info = user_data; - GError *error = NULL; - char * zone = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - G_TYPE_STRING, &zone, - G_TYPE_INVALID)) { - g_assert (error); - /* ignore UNKNOWN_INTERFACE errors */ - if (error->message && !strstr (error->message, "UNKNOWN_INTERFACE")) { - nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", - info->iface, info->id, error->code, error->message); - } else { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", - info->iface, info->id, error->code, error->message); - } - } else { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove succeeded [%u]", - info->iface, info->id); - } - - info->completed = TRUE; - g_free (zone); - g_clear_error (&error); -} - -gpointer -nm_firewall_manager_remove_from_zone (NMFirewallManager *self, - const char *iface, - const char *zone) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - CBInfo *info; - - if (priv->running == FALSE) { - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface); - return NULL; - } - - info = _cb_info_create (iface, NULL, NULL); - - nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s%s%s [%u]", iface, - zone?"\"":"", zone ? zone : "*", zone?"\"":"", info->id); - return dbus_g_proxy_begin_call_with_timeout (priv->proxy, - "removeInterface", - remove_cb, - info, - (GDestroyNotify) cb_info_free, - 10000, /* timeout */ - G_TYPE_STRING, zone ? zone : "", - G_TYPE_STRING, iface, - G_TYPE_INVALID); -} - -void nm_firewall_manager_cancel_call (NMFirewallManager *self, gpointer call) -{ - g_return_if_fail (NM_IS_FIREWALL_MANAGER (self)); - dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy, - (DBusGProxyCall *) call); -} - -static void -set_running (NMFirewallManager *self, gboolean now_running) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - gboolean old_running = priv->running; - - priv->running = now_running; - if (old_running != priv->running) - g_object_notify (G_OBJECT (self), NM_FIREWALL_MANAGER_AVAILABLE); -} - -static void -name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) -{ - NMFirewallManager *self = NM_FIREWALL_MANAGER (user_data); - gboolean old_owner_good = (old_owner && strlen (old_owner)); - gboolean new_owner_good = (new_owner && strlen (new_owner)); - - /* We only care about the firewall here */ - if (strcmp (FIREWALL_DBUS_SERVICE, name) != 0) - return; - - if (!old_owner_good && new_owner_good) { - nm_log_dbg (LOGD_FIREWALL, "firewall started"); - set_running (self, TRUE); - g_signal_emit (self, signals[STARTED], 0); - } else if (old_owner_good && !new_owner_good) { - nm_log_dbg (LOGD_FIREWALL, "firewall stopped"); - set_running (self, FALSE); - } -} - -/*******************************************************************/ - -NMFirewallManager * -nm_firewall_manager_get (void) -{ - static NMFirewallManager *singleton = NULL; - - if (!singleton) - singleton = NM_FIREWALL_MANAGER (g_object_new (NM_TYPE_FIREWALL_MANAGER, NULL)); - else - g_object_ref (singleton); - - g_assert (singleton); - return singleton; -} - -static void -nm_firewall_manager_init (NMFirewallManager * self) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); - DBusGConnection *bus; - - priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ()); - priv->name_owner_id = g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (name_owner_changed), - self); - priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, FIREWALL_DBUS_SERVICE); - nm_log_dbg (LOGD_FIREWALL, "firewall %s running", priv->running ? "is" : "is not" ); - - bus = nm_dbus_manager_get_connection (priv->dbus_mgr); - priv->proxy = dbus_g_proxy_new_for_name (bus, - FIREWALL_DBUS_SERVICE, - FIREWALL_DBUS_PATH, - FIREWALL_DBUS_INTERFACE_ZONE); -} - -static void -set_property (GObject *object, guint prop_id, 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) -{ - switch (prop_id) { - case PROP_AVAILABLE: - g_value_set_boolean (value, NM_FIREWALL_MANAGER_GET_PRIVATE (object)->running); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -dispose (GObject *object) -{ - NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (object); - - if (priv->dbus_mgr) { - g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); - priv->name_owner_id = 0; - g_clear_object (&priv->dbus_mgr); - } - - g_clear_object (&priv->proxy); - - /* Chain up to the parent class */ - G_OBJECT_CLASS (nm_firewall_manager_parent_class)->dispose (object); -} - -static void -nm_firewall_manager_class_init (NMFirewallManagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMFirewallManagerPrivate)); - - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - - g_object_class_install_property (object_class, PROP_AVAILABLE, - g_param_spec_boolean (NM_FIREWALL_MANAGER_AVAILABLE, - "Available", - "Available", - FALSE, - G_PARAM_READABLE)); - - signals[STARTED] = - g_signal_new ("started", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMFirewallManagerClass, started), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - -} - diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/firewall-manager/nm-firewall-manager.h deleted file mode 100644 index a77984e3..00000000 --- a/src/firewall-manager/nm-firewall-manager.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2011 Red Hat, Inc. - */ - -#ifndef NM_FIREWALL_MANAGER_H -#define NM_FIREWALL_MANAGER_H - -#include -#include - -#define FIREWALL_DBUS_SERVICE "org.fedoraproject.FirewallD1" -#define FIREWALL_DBUS_PATH "/org/fedoraproject/FirewallD1" -#define FIREWALL_DBUS_INTERFACE "org.fedoraproject.FirewallD1" -#define FIREWALL_DBUS_INTERFACE_ZONE "org.fedoraproject.FirewallD1.zone" - - -G_BEGIN_DECLS - -#define NM_TYPE_FIREWALL_MANAGER (nm_firewall_manager_get_type ()) -#define NM_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManager)) -#define NM_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) -#define NM_IS_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_FIREWALL_MANAGER)) -#define NM_IS_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FIREWALL_MANAGER)) -#define NM_FIREWALL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) - -#define NM_FIREWALL_MANAGER_AVAILABLE "available" - -typedef struct { - GObject parent; -} NMFirewallManager; - -typedef struct { - GObjectClass parent; - - /* Signals */ - void (*started) (NMFirewallManager *manager); -} NMFirewallManagerClass; - -GType nm_firewall_manager_get_type (void); - -NMFirewallManager *nm_firewall_manager_get (void); - -typedef void (*FwAddToZoneFunc) (GError *error, gpointer user_data); - -gpointer nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr, - const char *iface, - const char *zone, - gboolean add, - FwAddToZoneFunc callback, - gpointer user_data); -gpointer nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr, - const char *iface, - const char *zone); - -void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, gpointer fw_call); - -#endif /* NM_FIREWALL_MANAGER_H */ diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c deleted file mode 100644 index 1577f6ec..00000000 --- a/src/logging/nm-logging.c +++ /dev/null @@ -1,482 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2006 - 2012 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "nm-logging.h" - -static void -nm_log_handler (const gchar *log_domain, - GLogLevelFlags level, - const gchar *message, - gpointer ignored); - -#define LOGD_ALL \ - (LOGD_PLATFORM | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \ - LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_WIFI_SCAN | LOGD_IP4 | \ - LOGD_IP6 | LOGD_AUTOIP4 | LOGD_DNS | LOGD_VPN | LOGD_SHARING | \ - LOGD_SUPPLICANT | LOGD_AGENTS | LOGD_SETTINGS | LOGD_SUSPEND | \ - LOGD_CORE | LOGD_DEVICE | LOGD_OLPC | LOGD_WIMAX | \ - LOGD_INFINIBAND | LOGD_FIREWALL | LOGD_ADSL | LOGD_BOND | \ - LOGD_VLAN | LOGD_BRIDGE | LOGD_DBUS_PROPS | LOGD_TEAM | LOGD_CONCHECK | \ - LOGD_DCB | LOGD_DISPATCH) - -#define LOGD_DEFAULT (LOGD_ALL & ~(LOGD_WIFI_SCAN | LOGD_DBUS_PROPS)) - -static guint32 log_level = LOGL_INFO; -static char *log_domains; -static guint64 logging[LOGL_MAX]; -static gboolean logging_set_up; -static gboolean syslog_opened; - -typedef struct { - guint64 num; - const char *name; -} LogDesc; - -static const char *level_names[LOGL_MAX] = { - [LOGL_DEBUG] = "DEBUG", - [LOGL_INFO] = "INFO", - [LOGL_WARN] = "WARN", - [LOGL_ERR] = "ERR", -}; - -static const LogDesc domain_descs[] = { - { LOGD_NONE, "NONE" }, - { LOGD_PLATFORM, "PLATFORM" }, - { LOGD_RFKILL, "RFKILL" }, - { LOGD_ETHER, "ETHER" }, - { LOGD_WIFI, "WIFI" }, - { LOGD_BT, "BT" }, - { LOGD_MB, "MB" }, - { LOGD_DHCP4, "DHCP4" }, - { LOGD_DHCP6, "DHCP6" }, - { LOGD_PPP, "PPP" }, - { LOGD_WIFI_SCAN, "WIFI_SCAN" }, - { LOGD_IP4, "IP4" }, - { LOGD_IP6, "IP6" }, - { LOGD_AUTOIP4, "AUTOIP4" }, - { LOGD_DNS, "DNS" }, - { LOGD_VPN, "VPN" }, - { LOGD_SHARING, "SHARING" }, - { LOGD_SUPPLICANT,"SUPPLICANT" }, - { LOGD_AGENTS, "AGENTS" }, - { LOGD_SETTINGS, "SETTINGS" }, - { LOGD_SUSPEND, "SUSPEND" }, - { LOGD_CORE, "CORE" }, - { LOGD_DEVICE, "DEVICE" }, - { LOGD_OLPC, "OLPC" }, - { LOGD_WIMAX, "WIMAX" }, - { LOGD_INFINIBAND,"INFINIBAND" }, - { LOGD_FIREWALL, "FIREWALL" }, - { LOGD_ADSL, "ADSL" }, - { LOGD_BOND, "BOND" }, - { LOGD_VLAN, "VLAN" }, - { LOGD_BRIDGE, "BRIDGE" }, - { LOGD_DBUS_PROPS,"DBUS_PROPS" }, - { LOGD_TEAM, "TEAM" }, - { LOGD_CONCHECK, "CONCHECK" }, - { LOGD_DCB, "DCB" }, - { LOGD_DISPATCH, "DISPATCH" }, - { 0, NULL } -}; - -/* Combined domains */ -#define LOGD_ALL_STRING "ALL" -#define LOGD_DEFAULT_STRING "DEFAULT" -#define LOGD_DHCP_STRING "DHCP" -#define LOGD_IP_STRING "IP" - -/************************************************************************/ - -GQuark -nm_logging_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm_logging_error"); - return ret; -} - -/************************************************************************/ - -static gboolean -match_log_level (const char *level, - guint32 *out_level, - GError **error) -{ - int i; - - for (i = 0; i < LOGL_MAX; i++) { - if (!g_ascii_strcasecmp (level_names[i], level)) { - *out_level = i; - return TRUE; - } - } - - g_set_error (error, NM_LOGGING_ERROR, NM_LOGGING_ERROR_UNKNOWN_LEVEL, - _("Unknown log level '%s'"), level); - return FALSE; -} - -gboolean -nm_logging_setup (const char *level, - const char *domains, - char **bad_domains, - GError **error) -{ - GString *unrecognized = NULL; - guint64 new_logging[LOGL_MAX]; - guint32 new_log_level = log_level; - char **tmp, **iter; - int i; - - logging_set_up = TRUE; - - for (i = 0; i < LOGL_MAX; i++) - new_logging[i] = 0; - - /* levels */ - if (level && *level) { - if (!match_log_level (level, &new_log_level, error)) - return FALSE; - } - - /* domains */ - if (!domains || !*domains) - domains = log_domains ? log_domains : "DEFAULT"; - - tmp = g_strsplit_set (domains, ", ", 0); - for (iter = tmp; iter && *iter; iter++) { - const LogDesc *diter; - guint32 domain_log_level; - guint64 bits; - char *p; - - if (!strlen (*iter)) - continue; - - p = strchr (*iter, ':'); - if (p) { - *p = '\0'; - if (!match_log_level (p + 1, &domain_log_level, error)) { - g_strfreev (tmp); - return FALSE; - } - } else - domain_log_level = new_log_level; - - bits = 0; - - /* Check for combined domains */ - if (!g_ascii_strcasecmp (*iter, LOGD_ALL_STRING)) - bits = LOGD_ALL; - else if (!g_ascii_strcasecmp (*iter, LOGD_DEFAULT_STRING)) - bits = LOGD_DEFAULT; - else if (!g_ascii_strcasecmp (*iter, LOGD_DHCP_STRING)) - bits = LOGD_DHCP; - else if (!g_ascii_strcasecmp (*iter, LOGD_IP_STRING)) - bits = LOGD_IP; - - /* Check for compatibility domains */ - else if (!g_ascii_strcasecmp (*iter, "HW")) - bits = LOGD_PLATFORM; - - else { - for (diter = &domain_descs[0]; diter->name; diter++) { - if (!g_ascii_strcasecmp (diter->name, *iter)) { - bits = diter->num; - break; - } - } - } - - if (!bits) { - if (!bad_domains) { - g_set_error (error, NM_LOGGING_ERROR, NM_LOGGING_ERROR_UNKNOWN_DOMAIN, - _("Unknown log domain '%s'"), *iter); - return FALSE; - } - - if (unrecognized) - g_string_append (unrecognized, ", "); - else - unrecognized = g_string_new (NULL); - g_string_append (unrecognized, *iter); - continue; - } - - for (i = 0; i < domain_log_level; i++) - new_logging[i] &= ~bits; - for (i = domain_log_level; i < LOGL_MAX; i++) - new_logging[i] |= bits; - } - g_strfreev (tmp); - - if (log_domains != (char *)domains) { - g_free (log_domains); - log_domains = g_strdup (domains); - } - - log_level = new_log_level; - for (i = 0; i < LOGL_MAX; i++) - logging[i] = new_logging[i]; - - if (unrecognized) - *bad_domains = g_string_free (unrecognized, FALSE); - - return TRUE; -} - -char * -nm_logging_level_to_string (void) -{ - return g_strdup (level_names[log_level]); -} - -const char * -nm_logging_all_levels_to_string (void) -{ - static GString *str; - - if (G_UNLIKELY (!str)) { - int i; - - str = g_string_new (NULL); - for (i = 0; i < LOGL_MAX; i++) { - if (str->len) - g_string_append_c (str, ','); - g_string_append (str, level_names[i]); - } - } - - return str->str; -} - -char * -nm_logging_domains_to_string (void) -{ - const LogDesc *diter; - GString *str; - int i; - - /* We don't just return g_strdup (log_domains) because we want to expand - * "DEFAULT" and "ALL". - */ - - str = g_string_sized_new (75); - for (diter = &domain_descs[0]; diter->name; diter++) { - /* If it's set for any lower level, it will also be set for LOGL_ERR */ - if (!(diter->num & logging[LOGL_ERR])) - continue; - - if (str->len) - g_string_append_c (str, ','); - g_string_append (str, diter->name); - - /* Check if it's logging at a lower level than the default. */ - for (i = 0; i < log_level; i++) { - if (diter->num & logging[i]) { - g_string_append_printf (str, ":%s", level_names[i]); - break; - } - } - /* Check if it's logging at a higher level than the default. */ - if (!(diter->num & logging[log_level])) { - for (i = log_level + 1; i < LOGL_MAX; i++) { - if (diter->num & logging[i]) { - g_string_append_printf (str, ":%s", level_names[i]); - break; - } - } - } - } - return g_string_free (str, FALSE); -} - -const char * -nm_logging_all_domains_to_string (void) -{ - static GString *str; - - if (G_UNLIKELY (!str)) { - const LogDesc *diter; - - str = g_string_new (LOGD_DEFAULT_STRING); - for (diter = &domain_descs[0]; diter->name; diter++) { - g_string_append_c (str, ','); - g_string_append (str, diter->name); - if (diter->num == LOGD_DHCP6) - g_string_append (str, "," LOGD_DHCP_STRING); - else if (diter->num == LOGD_IP6) - g_string_append (str, "," LOGD_IP_STRING); - } - g_string_append (str, "," LOGD_ALL_STRING); - } - - return str->str; -} - -gboolean -nm_logging_enabled (guint32 level, guint64 domain) -{ - g_return_val_if_fail (level < LOGL_MAX, FALSE); - - return !!(logging[level] & domain); -} - -void -_nm_log (const char *loc, - const char *func, - guint64 domain, - guint32 level, - const char *fmt, - ...) -{ - va_list args; - char *msg; - char *fullmsg = NULL; - GTimeVal tv; - int syslog_level = LOG_INFO; - int g_log_level = G_LOG_LEVEL_INFO; - - g_return_if_fail (level < LOGL_MAX); - - if (G_UNLIKELY (!logging_set_up)) - nm_logging_setup ("INFO", "DEFAULT", NULL, NULL); - - if (!(logging[level] & domain)) - return; - - va_start (args, fmt); - msg = g_strdup_vprintf (fmt, args); - va_end (args); - - switch (level) { - case LOGL_DEBUG: - g_get_current_time (&tv); - syslog_level = LOG_INFO; - g_log_level = G_LOG_LEVEL_DEBUG; - fullmsg = g_strdup_printf (" [%ld.%06ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); - break; - case LOGL_INFO: - syslog_level = LOG_INFO; - g_log_level = G_LOG_LEVEL_MESSAGE; - fullmsg = g_strconcat (" ", msg, NULL); - break; - case LOGL_WARN: - syslog_level = LOG_WARNING; - g_log_level = G_LOG_LEVEL_WARNING; - fullmsg = g_strconcat (" ", msg, NULL); - break; - case LOGL_ERR: - syslog_level = LOG_ERR; - /* g_log_level is still WARNING, because ERROR is fatal */ - g_log_level = G_LOG_LEVEL_WARNING; - g_get_current_time (&tv); - fullmsg = g_strdup_printf (" [%ld.%06ld] [%s] %s(): %s", tv.tv_sec, tv.tv_usec, loc, func, msg); - break; - default: - g_assert_not_reached (); - } - - if (syslog_opened) - syslog (syslog_level, "%s", fullmsg); - else - g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); - - g_free (msg); - g_free (fullmsg); -} - -/************************************************************************/ - -static void -nm_log_handler (const gchar *log_domain, - GLogLevelFlags level, - const gchar *message, - gpointer ignored) -{ - int syslog_priority; - - switch (level & G_LOG_LEVEL_MASK) { - case G_LOG_LEVEL_ERROR: - syslog_priority = LOG_CRIT; - break; - case G_LOG_LEVEL_CRITICAL: - syslog_priority = LOG_ERR; - break; - case G_LOG_LEVEL_WARNING: - syslog_priority = LOG_WARNING; - break; - case G_LOG_LEVEL_MESSAGE: - syslog_priority = LOG_NOTICE; - break; - case G_LOG_LEVEL_DEBUG: - syslog_priority = LOG_DEBUG; - break; - case G_LOG_LEVEL_INFO: - default: - syslog_priority = LOG_INFO; - break; - } - - syslog (syslog_priority, "%s", message); -} - -void -nm_logging_syslog_openlog (gboolean debug) -{ - if (debug) - openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); - else - openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); - - if (!syslog_opened) { - syslog_opened = TRUE; - - g_log_set_handler (G_LOG_DOMAIN, - G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, - nm_log_handler, - NULL); - } -} - -void -nm_logging_syslog_closelog (void) -{ - if (syslog_opened) - closelog (); -} diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h deleted file mode 100644 index a53f93a5..00000000 --- a/src/logging/nm-logging.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2006 - 2012 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#ifndef NM_LOGGING_H -#define NM_LOGGING_H - -#ifdef __NM_TEST_UTILS_H__ -#error nm-test-utils.h must be included as last header -#endif - -#include -#include - -/* Log domains */ -enum { - LOGD_NONE = 0LL, - LOGD_PLATFORM = (1LL << 1), /* Platform services */ - LOGD_RFKILL = (1LL << 2), - LOGD_ETHER = (1LL << 3), - LOGD_WIFI = (1LL << 4), - LOGD_BT = (1LL << 5), - LOGD_MB = (1LL << 6), /* mobile broadband */ - LOGD_DHCP4 = (1LL << 7), - LOGD_DHCP6 = (1LL << 8), - LOGD_PPP = (1LL << 9), - LOGD_WIFI_SCAN = (1LL << 10), - LOGD_IP4 = (1LL << 11), - LOGD_IP6 = (1LL << 12), - LOGD_AUTOIP4 = (1LL << 13), - LOGD_DNS = (1LL << 14), - LOGD_VPN = (1LL << 15), - LOGD_SHARING = (1LL << 16), /* Connection sharing/dnsmasq */ - LOGD_SUPPLICANT = (1LL << 17), /* WiFi and 802.1x */ - LOGD_AGENTS = (1LL << 18), /* Secret agents */ - LOGD_SETTINGS = (1LL << 19), /* Settings */ - LOGD_SUSPEND = (1LL << 20), /* Suspend/Resume */ - LOGD_CORE = (1LL << 21), /* Core daemon and policy stuff */ - LOGD_DEVICE = (1LL << 22), /* Device state and activation */ - LOGD_OLPC = (1LL << 23), - LOGD_WIMAX = (1LL << 24), - LOGD_INFINIBAND = (1LL << 25), - LOGD_FIREWALL = (1LL << 26), - LOGD_ADSL = (1LL << 27), - LOGD_BOND = (1LL << 28), - LOGD_VLAN = (1LL << 29), - LOGD_BRIDGE = (1LL << 30), - LOGD_DBUS_PROPS = (1LL << 31), - LOGD_TEAM = (1LL << 32), - LOGD_CONCHECK = (1LL << 33), - LOGD_DCB = (1LL << 34), /* Data Center Bridging */ - LOGD_DISPATCH = (1LL << 35), -}; - -#define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6) -#define LOGD_IP (LOGD_IP4 | LOGD_IP6) -#define LOGD_HW LOGD_PLATFORM - -/* Log levels */ -enum { - LOGL_DEBUG, - LOGL_INFO, - LOGL_WARN, - LOGL_ERR, - - LOGL_MAX -}; - -typedef enum { - NM_LOGGING_ERROR_UNKNOWN_LEVEL = 0, /*< nick=UnknownLevel >*/ - NM_LOGGING_ERROR_UNKNOWN_DOMAIN = 1, /*< nick=UnknownDomain >*/ -} NMLoggingError; - -#define NM_LOGGING_ERROR (nm_logging_error_quark ()) -GQuark nm_logging_error_quark (void); - - -#define nm_log_err(domain, ...) \ - _nm_log (G_STRLOC, G_STRFUNC, domain, LOGL_ERR, ## __VA_ARGS__ ) - -#define nm_log_warn(domain, ...) \ - _nm_log (G_STRLOC, G_STRFUNC, domain, LOGL_WARN, ## __VA_ARGS__ ) - -#define nm_log_info(domain, ...) \ - _nm_log (G_STRLOC, G_STRFUNC, domain, LOGL_INFO, ## __VA_ARGS__ ) - -#define nm_log_dbg(domain, ...) \ - _nm_log (G_STRLOC, G_STRFUNC, domain, LOGL_DEBUG, ## __VA_ARGS__ ) - -#define nm_log(domain, level, ...) \ - _nm_log (G_STRLOC, G_STRFUNC, domain, level, ## __VA_ARGS__ ) - -void _nm_log (const char *loc, - const char *func, - guint64 domain, - guint32 level, - const char *fmt, - ...) __attribute__((__format__ (__printf__, 5, 6))); - -char *nm_logging_level_to_string (void); -char *nm_logging_domains_to_string (void); -gboolean nm_logging_enabled (guint32 level, guint64 domain); - -const char *nm_logging_all_levels_to_string (void); -const char *nm_logging_all_domains_to_string (void); - -/* Undefine the nm-utils.h logging stuff to ensure errors */ -#undef nm_get_timestamp -#undef nm_info -#undef nm_info_str -#undef nm_debug -#undef nm_debug_str -#undef nm_warning -#undef nm_warning_str -#undef nm_error -#undef nm_error_str - -gboolean nm_logging_setup (const char *level, - const char *domains, - char **bad_domains, - GError **error); -void nm_logging_syslog_openlog (gboolean debug); -void nm_logging_syslog_closelog (void); - -#endif /* NM_LOGGING_H */ diff --git a/src/main-utils.c b/src/main-utils.c new file mode 100644 index 00000000..0fa3644f --- /dev/null +++ b/src/main-utils.c @@ -0,0 +1,279 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2004 - 2012 Red Hat, Inc. + * Copyright (C) 2005 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "main-utils.h" +#include "nm-posix-signals.h" +#include "nm-logging.h" + +static sigset_t signal_set; +static gboolean *quit_early = NULL; + +/* + * Thread function waiting for signals and processing them. + * Wait for signals in signal set. The semantics of sigwait() require that all + * threads (including the thread calling sigwait()) have the signal masked, for + * reliable operation. Otherwise, a signal that arrives while this thread is + * not blocked in sigwait() might be delivered to another thread. + */ +static void * +signal_handling_thread (void *arg) +{ + GMainLoop *main_loop = arg; + int signo; + + while (1) { + sigwait (&signal_set, &signo); + + switch (signo) { + case SIGINT: + case SIGTERM: + nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo); + *quit_early = TRUE; /* for quitting before entering the main loop */ + g_main_loop_quit (main_loop); + break; + case SIGHUP: + /* Reread config stuff like system config files, VPN service files, etc */ + nm_log_info (LOGD_CORE, "caught signal %d, not supported yet.", signo); + break; + case SIGPIPE: + /* silently ignore signal */ + break; + default: + nm_log_err (LOGD_CORE, "caught unexpected signal %d", signo); + break; + } + } + return NULL; +} + +/** + * nm_main_utils_setup_signals: + * @main_loop: the #GMainLoop to quit when SIGINT or SIGTERM is received + * @quit_early: location of a variable that will be set to TRUE when + * SIGINT or SIGTERM is received + * + * Mask the signals we are interested in and create a signal handling thread. + * Because all threads inherit the signal mask from their creator, all threads + * in the process will have the signals masked. That's why setup_signals() has + * to be called before creating other threads. + * + * Returns: %TRUE on success + */ +gboolean +nm_main_utils_setup_signals (GMainLoop *main_loop, gboolean *quit_early_ptr) +{ + pthread_t signal_thread_id; + sigset_t old_sig_mask; + int status; + + g_return_val_if_fail (main_loop != NULL, FALSE); + g_return_val_if_fail (quit_early_ptr != NULL, FALSE); + + quit_early = quit_early_ptr; + + sigemptyset (&signal_set); + sigaddset (&signal_set, SIGHUP); + sigaddset (&signal_set, SIGINT); + sigaddset (&signal_set, SIGTERM); + sigaddset (&signal_set, SIGPIPE); + + /* Block all signals of interest. */ + status = pthread_sigmask (SIG_BLOCK, &signal_set, &old_sig_mask); + if (status != 0) { + fprintf (stderr, _("Failed to set signal mask: %d"), status); + return FALSE; + } + /* Save original mask so that we could use it for child processes. */ + nm_save_original_signal_mask (old_sig_mask); + + /* Create the signal handling thread. */ + status = pthread_create (&signal_thread_id, NULL, signal_handling_thread, main_loop); + if (status != 0) { + fprintf (stderr, _("Failed to create signal handling thread: %d"), status); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_main_utils_write_pidfile (const char *pidfile) +{ + char pid[16]; + int fd; + gboolean success = FALSE; + + if ((fd = open (pidfile, O_CREAT|O_WRONLY|O_TRUNC, 00644)) < 0) { + fprintf (stderr, _("Opening %s failed: %s\n"), pidfile, strerror (errno)); + return FALSE; + } + + g_snprintf (pid, sizeof (pid), "%d", getpid ()); + if (write (fd, pid, strlen (pid)) < 0) + fprintf (stderr, _("Writing to %s failed: %s\n"), pidfile, strerror (errno)); + else + success = TRUE; + + if (close (fd)) + fprintf (stderr, _("Closing %s failed: %s\n"), pidfile, strerror (errno)); + + return success; +} + +/** + * nm_main_utils_check_pidfile: + * @pidfile: the pid file + * @name: the process name + * + * Checks whether the pidfile already exists and contains PID of a running + * process. + * + * Returns: %TRUE if the specified pidfile already exists and contains the PID + * of a running process named @name, or %FALSE if not + */ +gboolean +nm_main_utils_check_pidfile (const char *pidfile, const char *name) +{ + char *contents = NULL; + gsize len = 0; + glong pid; + char *proc_cmdline = NULL; + gboolean nm_running = FALSE; + const char *process_name; + + /* Setup runtime directory */ + if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) { + nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMRUNDIR, strerror (errno)); + exit (1); + } + + if (!g_file_get_contents (pidfile, &contents, &len, NULL)) + return FALSE; + + if (len <= 0) + goto done; + + errno = 0; + pid = strtol (contents, NULL, 10); + if (pid <= 0 || pid > 65536 || errno) + goto done; + + g_free (contents); + proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid); + if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL)) + goto done; + + process_name = strrchr (contents, '/'); + if (process_name) + process_name++; + else + process_name = contents; + if (strcmp (process_name, name) == 0) { + /* Check that the process exists */ + if (kill (pid, 0) == 0) { + fprintf (stderr, _("%s is already running (pid %ld)\n"), name, pid); + nm_running = TRUE; + } + } + +done: + g_free (proc_cmdline); + g_free (contents); + return nm_running; +} + +gboolean +nm_main_utils_early_setup (const char *progname, + char **argv[], + int *argc, + GOptionEntry *options, + GOptionEntry *more_options, + const char *summary) +{ + GOptionContext *opt_ctx = NULL; + GError *error = NULL; + gboolean success = FALSE; + int i; + + /* Make GIO ignore the remote VFS service; otherwise it tries to use the + * session bus to contact the remote service, and NM shouldn't ever be + * talking on the session bus. See rh #588745 + */ + setenv ("GIO_USE_VFS", "local", 1); + + /* + * Set the umask to 0022, which results in 0666 & ~0022 = 0644. + * Otherwise, if root (or an su'ing user) has a wacky umask, we could + * write out an unreadable resolv.conf. + */ + umask (022); + + /* Ensure gettext() gets the right environment (bgo #666516) */ + setlocale (LC_ALL, ""); + textdomain (GETTEXT_PACKAGE); + + if (getuid () != 0) { + fprintf (stderr, _("You must be root to run %s!\n"), progname); + exit (1); + } + + for (i = 0; options[i].long_name; i++) { + if (!strcmp (options[i].long_name, "log-level")) + options[i].description = g_strdup_printf (options[i].description, nm_logging_all_levels_to_string ()); + else if (!strcmp (options[i].long_name, "log-domains")) + options[i].description = g_strdup_printf (options[i].description, nm_logging_all_domains_to_string ()); + } + + /* Parse options */ + opt_ctx = g_option_context_new (NULL); + g_option_context_set_translation_domain (opt_ctx, GETTEXT_PACKAGE); + g_option_context_set_ignore_unknown_options (opt_ctx, FALSE); + g_option_context_set_help_enabled (opt_ctx, TRUE); + g_option_context_add_main_entries (opt_ctx, options, NULL); + if (more_options) + g_option_context_add_main_entries (opt_ctx, more_options, NULL); + g_option_context_set_summary (opt_ctx, summary); + + success = g_option_context_parse (opt_ctx, argc, argv, &error); + if (!success) { + fprintf (stderr, _("%s. Please use --help to see a list of valid options.\n"), + error->message); + g_clear_error (&error); + } + g_option_context_free (opt_ctx); + + return success; +} + diff --git a/src/main-utils.h b/src/main-utils.h new file mode 100644 index 00000000..472fa5e7 --- /dev/null +++ b/src/main-utils.h @@ -0,0 +1,39 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef __MAIN_UTILS_H__ +#define __MAIN_UTILS_H__ + +#include + +gboolean nm_main_utils_setup_signals (GMainLoop *main_loop, gboolean *quit_early_ptr); + +gboolean nm_main_utils_write_pidfile (const char *pidfile); + +gboolean nm_main_utils_check_pidfile (const char *pidfile, const char *name); + +gboolean nm_main_utils_early_setup (const char *progname, + char **argv[], + int *argc, + GOptionEntry *options, + GOptionEntry *more_options, + const char *summary); + +#endif /* __MAIN_UTILS_H__ */ diff --git a/src/main.c b/src/main.c index 0ba65b0b..b3206fb4 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,8 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -39,9 +40,10 @@ #include #include -#include "libgsystem.h" -#include "NetworkManager.h" +#include "gsystem-local-alloc.h" +#include "nm-dbus-interface.h" #include "NetworkManagerUtils.h" +#include "main-utils.h" #include "nm-manager.h" #include "nm-linux-platform.h" #include "nm-dns-manager.h" @@ -55,6 +57,9 @@ #include "nm-posix-signals.h" #include "nm-session-monitor.h" #include "nm-dispatcher.h" +#include "nm-settings.h" +#include "nm-auth-manager.h" +#include "nm-core-internal.h" #if !defined(NM_DIST_VERSION) # define NM_DIST_VERSION VERSION @@ -63,157 +68,7 @@ #define NM_DEFAULT_PID_FILE NMRUNDIR "/NetworkManager.pid" #define NM_DEFAULT_SYSTEM_STATE_FILE NMSTATEDIR "/NetworkManager.state" -/* - * Globals - */ static GMainLoop *main_loop = NULL; -static gboolean quit_early = FALSE; -static sigset_t signal_set; - -void *signal_handling_thread (void *arg); -/* - * Thread function waiting for signals and processing them. - * Wait for signals in signal set. The semantics of sigwait() require that all - * threads (including the thread calling sigwait()) have the signal masked, for - * reliable operation. Otherwise, a signal that arrives while this thread is - * not blocked in sigwait() might be delivered to another thread. - */ -void * -signal_handling_thread (void *arg) -{ - int signo; - - while (1) { - sigwait (&signal_set, &signo); - - switch (signo) { - case SIGINT: - case SIGTERM: - nm_log_info (LOGD_CORE, "caught signal %d, shutting down normally.", signo); - quit_early = TRUE; /* for quitting before entering the main loop */ - g_main_loop_quit (main_loop); - break; - case SIGHUP: - /* Reread config stuff like system config files, VPN service files, etc */ - nm_log_info (LOGD_CORE, "caught signal %d, not supported yet.", signo); - break; - default: - nm_log_err (LOGD_CORE, "caught unexpected signal %d", signo); - break; - } - } - return NULL; -} - -/* - * Mask the signals we are interested in and create a signal handling thread. - * Because all threads inherit the signal mask from their creator, all threads - * in the process will have the signals masked. That's why setup_signals() has - * to be called before creating other threads. - */ -static gboolean -setup_signals (void) -{ - pthread_t signal_thread_id; - sigset_t old_sig_mask; - int status; - - sigemptyset (&signal_set); - sigaddset (&signal_set, SIGHUP); - sigaddset (&signal_set, SIGINT); - sigaddset (&signal_set, SIGTERM); - - /* Block all signals of interest. */ - status = pthread_sigmask (SIG_BLOCK, &signal_set, &old_sig_mask); - if (status != 0) { - fprintf (stderr, _("Failed to set signal mask: %d"), status); - return FALSE; - } - /* Save original mask so that we could use it for child processes. */ - nm_save_original_signal_mask (old_sig_mask); - - /* Create the signal handling thread. */ - status = pthread_create (&signal_thread_id, NULL, signal_handling_thread, NULL); - if (status != 0) { - fprintf (stderr, _("Failed to create signal handling thread: %d"), status); - return FALSE; - } - - return TRUE; -} - -static gboolean -write_pidfile (const char *pidfile) -{ - char pid[16]; - int fd; - gboolean success = FALSE; - - if ((fd = open (pidfile, O_CREAT|O_WRONLY|O_TRUNC, 00644)) < 0) { - fprintf (stderr, _("Opening %s failed: %s\n"), pidfile, strerror (errno)); - return FALSE; - } - - g_snprintf (pid, sizeof (pid), "%d", getpid ()); - if (write (fd, pid, strlen (pid)) < 0) - fprintf (stderr, _("Writing to %s failed: %s\n"), pidfile, strerror (errno)); - else - success = TRUE; - - if (close (fd)) - fprintf (stderr, _("Closing %s failed: %s\n"), pidfile, strerror (errno)); - - return success; -} - -/* Check whether the pidfile already exists and contains PID of a running NetworkManager - * Returns: FALSE - specified pidfile doesn't exist or doesn't contain PID of a running NM process - * TRUE - specified pidfile already exists and contains PID of a running NM process - */ -static gboolean -check_pidfile (const char *pidfile) -{ - char *contents = NULL; - gsize len = 0; - glong pid; - char *proc_cmdline = NULL; - gboolean nm_running = FALSE; - const char *process_name; - - if (!g_file_get_contents (pidfile, &contents, &len, NULL)) - return FALSE; - - if (len <= 0) - goto done; - - errno = 0; - pid = strtol (contents, NULL, 10); - if (pid <= 0 || pid > 65536 || errno) - goto done; - - g_free (contents); - proc_cmdline = g_strdup_printf ("/proc/%ld/cmdline", pid); - if (!g_file_get_contents (proc_cmdline, &contents, &len, NULL)) - goto done; - - process_name = strrchr (contents, '/'); - if (process_name) - process_name++; - else - process_name = contents; - if (strcmp (process_name, "NetworkManager") == 0) { - /* Check that the process exists */ - if (kill (pid, 0) == 0) { - fprintf (stderr, _("NetworkManager is already running (pid %ld)\n"), pid); - nm_running = TRUE; - } - } - -done: - g_free (proc_cmdline); - g_free (contents); - return nm_running; -} static gboolean parse_state_file (const char *filename, @@ -324,6 +179,13 @@ _init_nm_debug (const char *debug) } } +static void +manager_configure_quit (NMManager *manager, gpointer user_data) +{ + nm_log_info (LOGD_CORE, "quitting now that startup is complete"); + g_main_loop_quit (main_loop); +} + /* * main * @@ -331,7 +193,6 @@ _init_nm_debug (const char *debug) int main (int argc, char *argv[]) { - GOptionContext *opt_ctx = NULL; char *opt_log_level = NULL; char *opt_log_domains = NULL; gboolean become_daemon = TRUE, run_from_build_dir = FALSE; @@ -341,13 +202,12 @@ main (int argc, char *argv[]) gs_free char *state_file = NULL; gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success, show_version = FALSE; - int i; NMManager *manager = NULL; - gs_unref_object NMVPNManager *vpn_manager = NULL; + gs_unref_object NMVpnManager *vpn_manager = NULL; gs_unref_object NMDnsManager *dns_mgr = NULL; gs_unref_object NMDBusManager *dbus_mgr = NULL; gs_unref_object NMSupplicantManager *sup_mgr = NULL; - gs_unref_object NMDHCPManager *dhcp_mgr = NULL; + gs_unref_object NMDhcpManager *dhcp_mgr = NULL; gs_unref_object NMFirewallManager *fw_mgr = NULL; gs_unref_object NMSettings *settings = NULL; gs_unref_object NMConfig *config = NULL; @@ -355,6 +215,7 @@ main (int argc, char *argv[]) GError *error = NULL; gboolean wrote_pidfile = FALSE; char *bad_domains = NULL; + gboolean quit_early = FALSE; GOptionEntry options[] = { { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL }, @@ -371,66 +232,17 @@ main (int argc, char *argv[]) {NULL} }; - /* Make GIO ignore the remote VFS service; otherwise it tries to use the - * session bus to contact the remote service, and NM shouldn't ever be - * talking on the session bus. See rh #588745 - */ - setenv ("GIO_USE_VFS", "local", 1); - - /* - * Set the umask to 0022, which results in 0666 & ~0022 = 0644. - * Otherwise, if root (or an su'ing user) has a wacky umask, we could - * write out an unreadable resolv.conf. - */ - umask (022); - - /* Set locale to be able to use environment variables */ - setlocale (LC_ALL, ""); - - bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); + _nm_utils_is_manager_process = TRUE; - if (!g_module_supported ()) { - fprintf (stderr, _("GModules are not supported on your platform!\n")); - exit (1); - } - - if (getuid () != 0) { - fprintf (stderr, _("You must be root to run NetworkManager!\n")); - exit (1); - } - - for (i = 0; options[i].long_name; i++) { - if (!strcmp (options[i].long_name, "log-level")) { - options[i].description = g_strdup_printf (options[i].description, - nm_logging_all_levels_to_string ()); - } else if (!strcmp (options[i].long_name, "log-domains")) { - options[i].description = g_strdup_printf (options[i].description, - nm_logging_all_domains_to_string ()); - } - } - - /* Parse options */ - opt_ctx = g_option_context_new (NULL); - g_option_context_set_translation_domain (opt_ctx, GETTEXT_PACKAGE); - g_option_context_set_ignore_unknown_options (opt_ctx, FALSE); - g_option_context_set_help_enabled (opt_ctx, TRUE); - g_option_context_add_main_entries (opt_ctx, options, NULL); - g_option_context_add_main_entries (opt_ctx, nm_config_get_options (), NULL); - - g_option_context_set_summary (opt_ctx, - _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with.")); - - success = g_option_context_parse (opt_ctx, &argc, &argv, &error); - g_option_context_free (opt_ctx); + main_loop = g_main_loop_new (NULL, FALSE); - if (!success) { - fprintf (stderr, _("%s. Please use --help to see a list of valid options.\n"), - error->message); - g_clear_error (&error); + if (!nm_main_utils_early_setup ("NetworkManager", + &argv, + &argc, + options, + nm_config_get_options (), + _("NetworkManager monitors all network connections and automatically\nchooses the best connection to use. It also allows the user to\nspecify wireless access points which wireless cards in the computer\nshould associate with."))) exit (1); - } if (show_version) { fprintf (stdout, NM_DIST_VERSION "\n"); @@ -476,12 +288,6 @@ main (int argc, char *argv[]) g_free (path); } - /* Setup runtime directory */ - if (g_mkdir_with_parents (NMRUNDIR, 0755) != 0) { - nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMRUNDIR, strerror (errno)); - exit (1); - } - /* Ensure state directory exists */ if (g_mkdir_with_parents (NMSTATEDIR, 0755) != 0) { nm_log_err (LOGD_CORE, "Cannot create '%s': %s", NMSTATEDIR, strerror (errno)); @@ -492,7 +298,7 @@ main (int argc, char *argv[]) state_file = state_file ? state_file : g_strdup (NM_DEFAULT_SYSTEM_STATE_FILE); /* check pid file */ - if (check_pidfile (pidfile)) + if (nm_main_utils_check_pidfile (pidfile, "NetworkManager")) exit (1); /* Read the config file and CLI overrides */ @@ -543,14 +349,13 @@ main (int argc, char *argv[]) saved_errno); exit (1); } - if (write_pidfile (pidfile)) - wrote_pidfile = TRUE; + wrote_pidfile = nm_main_utils_write_pidfile (pidfile); } _init_nm_debug (nm_config_get_debug (config)); /* Set up unix signal handling - before creating threads, but after daemonizing! */ - if (!setup_signals ()) + if (!nm_main_utils_setup_signals (main_loop, &quit_early)) exit (1); if (g_fatal_warnings) { @@ -586,11 +391,11 @@ main (int argc, char *argv[]) #endif ); - main_loop = g_main_loop_new (NULL, FALSE); - /* Set up platform interaction layer */ nm_linux_platform_setup (); + nm_auth_manager_setup (nm_config_get_auth_polkit (config)); + /* Initialize our DBus service & connection */ dbus_mgr = nm_dbus_manager_get (); g_assert (dbus_mgr != NULL); @@ -654,6 +459,8 @@ main (int argc, char *argv[]) } } + g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config); + nm_manager_start (manager); /* Make sure the loopback interface is up. If interface is down, we bring @@ -672,10 +479,10 @@ main (int argc, char *argv[]) success = TRUE; /* Told to quit before getting to the mainloop by the signal handler */ - if (quit_early == TRUE) - goto done; + if (!quit_early) + g_main_loop_run (main_loop); - g_main_loop_run (main_loop); + nm_manager_stop (manager); done: g_clear_object (&manager); diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 9f9ee0f9..30ce7515 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -25,9 +25,8 @@ #include #include #include -#include -#include "libgsystem.h" +#include "gsystem-local-alloc.h" #include "nm-activation-request.h" #include "nm-logging.h" @@ -37,7 +36,7 @@ #include "nm-active-connection.h" #include "nm-settings-connection.h" #include "nm-posix-signals.h" - +#include "nm-auth-subject.h" G_DEFINE_TYPE (NMActRequest, nm_act_request, NM_TYPE_ACTIVE_CONNECTION) @@ -106,7 +105,7 @@ get_secrets_cb (NMSettingsConnection *connection, guint32 nm_act_request_get_secrets (NMActRequest *self, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data) @@ -128,7 +127,7 @@ nm_act_request_get_secrets (NMActRequest *self, info->callback_data = callback_data; if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_USER_REQUESTED; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self)); call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection), diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 87ea41f9..69756069 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -18,15 +18,15 @@ * (C) Copyright 2005 - 2012 Red Hat, Inc. */ -#ifndef NM_ACTIVATION_REQUEST_H -#define NM_ACTIVATION_REQUEST_H +#ifndef __NETWORKMANAGER_ACTIVATION_REQUEST_H__ +#define __NETWORKMANAGER_ACTIVATION_REQUEST_H__ #include #include + #include "nm-types.h" #include "nm-connection.h" #include "nm-active-connection.h" -#include "nm-settings-flags.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -35,9 +35,9 @@ #define NM_IS_ACT_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ACT_REQUEST)) #define NM_ACT_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACT_REQUEST, NMActRequestClass)) -typedef struct { +struct _NMActRequest { NMActiveConnection parent; -} NMActRequest; +}; typedef struct { NMActiveConnectionClass parent; @@ -71,12 +71,12 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, guint32 nm_act_request_get_secrets (NMActRequest *req, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data); void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id); -#endif /* NM_ACTIVATION_REQUEST_H */ +#endif /* __NETWORKMANAGER_ACTIVATION_REQUEST_H__ */ diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 172aa614..d0b5b875 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -18,19 +18,24 @@ * Copyright (C) 2008 - 2014 Red Hat, Inc. */ +#include "config.h" + #include + #include "nm-types.h" #include "nm-active-connection.h" -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-logging.h" #include "nm-dbus-glib-types.h" #include "nm-dbus-manager.h" #include "nm-device.h" #include "nm-settings-connection.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" +#include "nm-auth-subject.h" #include "NetworkManagerUtils.h" - +#include "gsystem-local-alloc.h" #include "nm-active-connection-glue.h" +#include "nm-glib-compat.h" /* Base class for anything implementing the Connection.Active D-Bus interface */ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, G_TYPE_OBJECT) @@ -50,6 +55,7 @@ typedef struct { gboolean is_default; gboolean is_default6; NMActiveConnectionState state; + gboolean state_set; gboolean vpn; NMAuthSubject *subject; @@ -92,6 +98,12 @@ enum { LAST_PROP }; +enum { + DEVICE_CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + static void check_master_ready (NMActiveConnection *self); static void _device_cleanup (NMActiveConnection *self); @@ -137,6 +149,7 @@ nm_active_connection_set_state (NMActiveConnection *self, old_state = priv->state; priv->state = new_state; + priv->state_set = TRUE; g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); check_master_ready (self); @@ -197,6 +210,17 @@ nm_active_connection_get_connection (NMActiveConnection *self) return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection; } +const char * +nm_active_connection_get_connection_type (NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + if (priv->connection == NULL) + return NULL; + + return nm_connection_get_connection_type (priv->connection); +} + void nm_active_connection_set_connection (NMActiveConnection *self, NMConnection *connection) @@ -250,6 +274,8 @@ nm_active_connection_set_default (NMActiveConnection *self, gboolean is_default) g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + is_default = !!is_default; + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); if (priv->is_default == is_default) return; @@ -273,6 +299,8 @@ nm_active_connection_set_default6 (NMActiveConnection *self, gboolean is_default g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + is_default6 = !!is_default6; + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); if (priv->is_default6 == is_default6) return; @@ -314,7 +342,7 @@ nm_active_connection_get_user_requested (NMActiveConnection *self) { g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); - return !nm_auth_subject_get_internal (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject); + return nm_auth_subject_is_unix_process (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->subject); } NMDevice * @@ -360,11 +388,11 @@ device_master_changed (GObject *object, return; if (!nm_device_get_master (device)) return; + if (!nm_active_connection_get_master (self)) + return; g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_master_changed), self); master = nm_active_connection_get_master (self); - g_assert (master); - master_state = nm_active_connection_get_state (master); if (master_state >= NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { /* Master failed before attaching the slave */ @@ -377,20 +405,23 @@ gboolean nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device) { NMActiveConnectionPrivate *priv; + gs_unref_object NMDevice *old_device = NULL; g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); g_return_val_if_fail (!device || NM_IS_DEVICE (device), FALSE); priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + if (device == priv->device) + return TRUE; - if (device) { - g_return_val_if_fail (priv->device == NULL, FALSE); + old_device = priv->device ? g_object_ref (priv->device) : NULL; + _device_cleanup (self); + if (device) { /* Device obviously can't be its own master */ g_return_val_if_fail (!priv->master || device != nm_active_connection_get_device (priv->master), FALSE); priv->device = g_object_ref (device); - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_DEVICE); g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), self); @@ -401,7 +432,14 @@ nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device) priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)self); nm_device_add_pending_action (device, priv->pending_activation_id, TRUE); } - } + } else + priv->device = NULL; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_INT_DEVICE); + + g_signal_emit (self, signals[DEVICE_CHANGED], 0, priv->device, old_device); + + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES); + return TRUE; } @@ -696,10 +734,10 @@ set_property (GObject *object, guint prop_id, priv->specific_object = g_value_dup_boxed (value); break; case PROP_DEFAULT: - priv->is_default = g_value_get_boolean (value); + priv->is_default = !!g_value_get_boolean (value); break; case PROP_DEFAULT6: - priv->is_default6 = g_value_get_boolean (value); + priv->is_default6 = !!g_value_get_boolean (value); break; case PROP_VPN: priv->vpn = g_value_get_boolean (value); @@ -743,7 +781,14 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, devices); break; case PROP_STATE: - g_value_set_uint (value, priv->state); + if (priv->state_set) + g_value_set_uint (value, priv->state); + else { + /* When the AC has just been created, its externally-visible state should + * be "ACTIVATING", even though internally it is "UNKNOWN". + */ + g_value_set_uint (value, NM_ACTIVE_CONNECTION_STATE_ACTIVATING); + } break; case PROP_DEFAULT: g_value_set_boolean (value, priv->is_default); @@ -847,147 +892,155 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) object_class->dispose = dispose; /* D-Bus exported properties */ - g_object_class_install_property (object_class, PROP_CONNECTION, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, - "Connection", - "Connection", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_ID, - g_param_spec_string (NM_ACTIVE_CONNECTION_ID, - "Connection ID", - "Connection ID", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_UUID, - g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, - "Connection UUID", - "Connection UUID", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_TYPE, - g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, - "Connection Type", - "Connection Type", - NULL, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_SPECIFIC_OBJECT, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, - "Specific object", - "Specific object", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_DEVICES, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, - "Devices", - "Devices", - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, - "State", - "State", - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_DEFAULT, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, - "Default", - "Is the default IPv4 active connection", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_IP4_CONFIG, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_IP4_CONFIG, - "IP4 Config", - "IP4 Config", + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_ID, + g_param_spec_string (NM_ACTIVE_CONNECTION_ID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UUID, + g_param_spec_string (NM_ACTIVE_CONNECTION_UUID, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_TYPE, + g_param_spec_string (NM_ACTIVE_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_SPECIFIC_OBJECT, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, "", "", + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, "", "", + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_DEFAULT, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_IP4_CONFIG, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_DHCP4_CONFIG, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, - "DHCP4 Config", - "DHCP4 Config", + g_object_class_install_property + (object_class, PROP_DHCP4_CONFIG, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DHCP4_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_DEFAULT6, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, - "Default6", - "Is the default IPv6 active connection", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_IP6_CONFIG, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_IP6_CONFIG, - "IP6 Config", - "IP6 Config", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_DEFAULT6, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_IP6_CONFIG, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_IP6_CONFIG, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_DHCP6_CONFIG, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, - "DHCP6 Config", - "DHCP6 Config", + g_object_class_install_property + (object_class, PROP_DHCP6_CONFIG, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DHCP6_CONFIG, "", "", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, "", "", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_MASTER, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_MASTER, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_VPN, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, - "VPN", - "Is a VPN connection", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_MASTER, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_MASTER, - "Master", - "Path of master device", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Internal properties */ - g_object_class_install_property (object_class, PROP_INT_CONNECTION, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_CONNECTION, - "Internal Connection", - "Internal connection", - NM_TYPE_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_INT_DEVICE, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_DEVICE, - "Internal device", - "Internal device", - NM_TYPE_DEVICE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_INT_SUBJECT, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SUBJECT, - "Subject", - "Subject", - NM_TYPE_AUTH_SUBJECT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_INT_MASTER, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_MASTER, - "Internal master active connection", - "Internal active connection", - NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_INT_MASTER_READY, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_MASTER_READY, - "Internal master active connection ready for slaves", - "Internal active connection ready", - FALSE, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_INT_CONNECTION, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_CONNECTION, "", "", + NM_TYPE_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_INT_DEVICE, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_DEVICE, "", "", + NM_TYPE_DEVICE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_INT_SUBJECT, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SUBJECT, "", "", + NM_TYPE_AUTH_SUBJECT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_INT_MASTER, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_MASTER, "", "", + NM_TYPE_ACTIVE_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_INT_MASTER_READY, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_INT_MASTER_READY, "", "", + FALSE, G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + signals[DEVICE_CHANGED] = + g_signal_new (NM_ACTIVE_CONNECTION_DEVICE_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMActiveConnectionClass, device_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 2, NM_TYPE_DEVICE, NM_TYPE_DEVICE); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (ac_class), diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 0d96c872..710cfeed 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -18,13 +18,12 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#ifndef NM_ACTIVE_CONNECTION_H -#define NM_ACTIVE_CONNECTION_H +#ifndef __NETWORKMANAGER_ACTIVE_CONNECTION_H__ +#define __NETWORKMANAGER_ACTIVE_CONNECTION_H__ #include #include "nm-types.h" #include "nm-connection.h" -#include "nm-auth-subject.h" #define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ()) #define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) @@ -57,9 +56,12 @@ #define NM_ACTIVE_CONNECTION_INT_MASTER "int-master" #define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready" -typedef struct { +/* Internal signals*/ +#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed" + +struct _NMActiveConnection { GObject parent; -} NMActiveConnection; +}; typedef struct { GObjectClass parent; @@ -72,6 +74,10 @@ typedef struct { NMDeviceState new_state, NMDeviceState old_state); void (*master_failed) (NMActiveConnection *connection); + + void (*device_changed) (NMActiveConnection *connection, + NMDevice *new_device, + NMDevice *old_device); } NMActiveConnectionClass; GType nm_active_connection_get_type (void); @@ -142,4 +148,4 @@ void nm_active_connection_set_assumed (NMActiveConnection *self, gboolean nm_active_connection_get_assumed (NMActiveConnection *self); -#endif /* NM_ACTIVE_CONNECTION_H */ +#endif /* __NETWORKMANAGER_ACTIVE_CONNECTION_H__ */ diff --git a/src/nm-auth-manager.c b/src/nm-auth-manager.c new file mode 100644 index 00000000..fc8f8cda --- /dev/null +++ b/src/nm-auth-manager.c @@ -0,0 +1,657 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "nm-auth-manager.h" + +#include "nm-logging.h" +#include "nm-errors.h" + +#define POLKIT_SERVICE "org.freedesktop.PolicyKit1" +#define POLKIT_OBJECT_PATH "/org/freedesktop/PolicyKit1/Authority" +#define POLKIT_INTERFACE "org.freedesktop.PolicyKit1.Authority" + + +#define _LOG_DEFAULT_DOMAIN LOGD_CORE + +#define _LOG(level, domain, ...) \ + G_STMT_START { \ + if (nm_logging_enabled ((level), (domain))) { \ + char __prefix[30] = "auth"; \ + \ + if ((self) != _instance) \ + g_snprintf (__prefix, sizeof (__prefix), "auth[%p]", (self)); \ + nm_log ((level), (domain), \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +#define _LOGD(...) _LOG (LOGL_DEBUG, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGI(...) _LOG (LOGL_INFO, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGW(...) _LOG (LOGL_WARN, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) +#define _LOGE(...) _LOG (LOGL_ERR, _LOG_DEFAULT_DOMAIN, __VA_ARGS__) + + +enum { + PROP_0, + PROP_POLKIT_ENABLED, + + LAST_PROP +}; + +enum { + CHANGED_SIGNAL, + + LAST_SIGNAL, +}; + +static guint signals[LAST_SIGNAL] = {0}; + +typedef struct { + gboolean polkit_enabled; +#if WITH_POLKIT + guint call_id_counter; + GCancellable *new_proxy_cancellable; + GSList *queued_calls; + GDBusProxy *proxy; +#endif +} NMAuthManagerPrivate; + +static NMAuthManager *_instance = NULL; + +G_DEFINE_TYPE (NMAuthManager, nm_auth_manager, G_TYPE_OBJECT) + +#define NM_AUTH_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AUTH_MANAGER, NMAuthManagerPrivate)) + +/*****************************************************************************/ + +gboolean +nm_auth_manager_get_polkit_enabled (NMAuthManager *self) +{ + g_return_val_if_fail (NM_IS_AUTH_MANAGER (self), FALSE); + + return NM_AUTH_MANAGER_GET_PRIVATE (self)->polkit_enabled; +} + +/*****************************************************************************/ + +#if WITH_POLKIT + +typedef enum { + POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE = 0, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION = (1<<0), +} PolkitCheckAuthorizationFlags; + +typedef struct { + guint call_id; + NMAuthManager *self; + GSimpleAsyncResult *simple; + gchar *cancellation_id; + GVariant *dbus_parameters; + GCancellable *cancellable; +} CheckAuthData; + +static void +_check_auth_data_free (CheckAuthData *data) +{ + if (data->dbus_parameters) + g_variant_unref (data->dbus_parameters); + g_object_unref (data->self); + g_object_unref (data->simple); + g_clear_object (&data->cancellable); + g_free (data->cancellation_id); + g_free (data); +} + +static void +_call_check_authorization_complete_with_error (CheckAuthData *data, + const char *error_message) +{ + NMAuthManager *self = data->self; + + _LOGD ("call[%u]: CheckAuthorization failed due to internal error: %s", data->call_id, error_message); + g_simple_async_result_set_error (data->simple, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Authorization check failed: %s", + error_message); + + g_simple_async_result_complete_in_idle (data->simple); + + _check_auth_data_free (data); +} + +static void +cancel_check_authorization_cb (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + NMAuthManager *self = user_data; + GVariant *value; + GError *error= NULL; + + value = g_dbus_proxy_call_finish (proxy, res, &error); + if (value == NULL) { + _LOGD ("Error cancelling authorization check: %s", error->message); + g_error_free (error); + } else + g_variant_unref (value); + + g_object_unref (self); +} + +typedef struct { + gboolean is_authorized; + gboolean is_challenge; +} CheckAuthorizationResult; + +static void +check_authorization_cb (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + CheckAuthData *data = user_data; + NMAuthManager *self = data->self; + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + GVariant *value; + GError *error = NULL; + + value = g_dbus_proxy_call_finish (proxy, res, &error); + if (value == NULL) { + if (data->cancellation_id != NULL && + (!g_dbus_error_is_remote_error (error) && + error->domain == G_IO_ERROR && + error->code == G_IO_ERROR_CANCELLED)) { + _LOGD ("call[%u]: CheckAuthorization cancelled", data->call_id); + g_dbus_proxy_call (priv->proxy, + "CancelCheckAuthorization", + g_variant_new ("(s)", data->cancellation_id), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + (GAsyncReadyCallback) cancel_check_authorization_cb, + g_object_ref (self)); + } else + _LOGD ("call[%u]: CheckAuthorization failed: %s", data->call_id, error->message); + g_simple_async_result_set_error (data->simple, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Authorization check failed: %s", + error->message); + g_error_free (error); + } else { + GVariant *result_value; + CheckAuthorizationResult *result; + + result = g_new0 (CheckAuthorizationResult, 1); + + result_value = g_variant_get_child_value (value, 0); + g_variant_get (result_value, + "(bb@a{ss})", + &result->is_authorized, + &result->is_challenge, + NULL); + g_variant_unref (result_value); + g_variant_unref (value); + + _LOGD ("call[%u]: CheckAuthorization succeeded: (is_authorized=%d, is_challenge=%d)", data->call_id, result->is_authorized, result->is_challenge); + g_simple_async_result_set_op_res_gpointer (data->simple, result, g_free); + } + + g_simple_async_result_complete (data->simple); + + _check_auth_data_free (data); +} + +static void +_call_check_authorization (CheckAuthData *data) +{ + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (data->self); + + g_dbus_proxy_call (priv->proxy, + "CheckAuthorization", + data->dbus_parameters, + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, /* no timeout */ + data->cancellable, + (GAsyncReadyCallback) check_authorization_cb, + data); + g_clear_object (&data->cancellable); + data->dbus_parameters = NULL; +} + +void +nm_auth_manager_polkit_authority_check_authorization (NMAuthManager *self, + NMAuthSubject *subject, + const char *action_id, + gboolean allow_user_interaction, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMAuthManagerPrivate *priv; + char subject_buf[64]; + GVariantBuilder builder; + PolkitCheckAuthorizationFlags flags; + GVariant *subject_value; + GVariant *details_value; + CheckAuthData *data; + + g_return_if_fail (NM_IS_AUTH_MANAGER (self)); + g_return_if_fail (NM_IS_AUTH_SUBJECT (subject)); + g_return_if_fail (nm_auth_subject_is_unix_process (subject)); + g_return_if_fail (action_id != NULL); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + + g_return_if_fail (priv->polkit_enabled); + + flags = allow_user_interaction + ? POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION + : POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; + + subject_value = nm_auth_subject_unix_process_to_polkit_gvariant (subject); + g_assert (g_variant_is_floating (subject_value)); + + /* ((PolkitDetails *)NULL) */ + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + details_value = g_variant_builder_end (&builder); + + data = g_new0 (CheckAuthData, 1); + data->call_id = ++priv->call_id_counter; + data->self = g_object_ref (self); + data->simple = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + nm_auth_manager_polkit_authority_check_authorization); + if (cancellable != NULL) { + data->cancellation_id = g_strdup_printf ("cancellation-id-%u", data->call_id); + data->cancellable = g_object_ref (cancellable); + } + + data->dbus_parameters = g_variant_new ("(@(sa{sv})s@a{ss}us)", + subject_value, + action_id, + details_value, + (guint32) flags, + data->cancellation_id != NULL ? data->cancellation_id : ""); + + if (priv->new_proxy_cancellable) { + _LOGD ("call[%u]: CheckAuthorization(%s), subject=%s (wait for proxy)", data->call_id, action_id, nm_auth_subject_to_string (subject, subject_buf, sizeof (subject_buf))); + + priv->queued_calls = g_slist_prepend (priv->queued_calls, data); + } else if (!priv->proxy) { + _LOGD ("call[%u]: CheckAuthorization(%s), subject=%s (fails due to invalid DBUS proxy)", data->call_id, action_id, nm_auth_subject_to_string (subject, subject_buf, sizeof (subject_buf))); + + _call_check_authorization_complete_with_error (data, "invalid DBUS proxy"); + } else { + _LOGD ("call[%u]: CheckAuthorization(%s), subject=%s", data->call_id, action_id, nm_auth_subject_to_string (subject, subject_buf, sizeof (subject_buf))); + + _call_check_authorization (data); + } +} + +gboolean +nm_auth_manager_polkit_authority_check_authorization_finish (NMAuthManager *self, + GAsyncResult *res, + gboolean *out_is_authorized, + gboolean *out_is_challenge, + GError **error) +{ + gboolean success = FALSE; + gboolean is_authorized = FALSE; + gboolean is_challenge = FALSE; + + g_return_val_if_fail (NM_IS_AUTH_MANAGER (self), FALSE); + g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) { + CheckAuthorizationResult *result; + + result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + is_authorized = !!result->is_authorized; + is_challenge = !!result->is_challenge; + success = TRUE; + } + g_assert ((success && !error) || (!success || error)); + + if (out_is_authorized) + *out_is_authorized = is_authorized; + if (out_is_challenge) + *out_is_challenge = is_challenge; + return success; +} + +/*****************************************************************************/ + +static void +_emit_changed_signal (NMAuthManager *self) +{ + _LOGD ("emit changed signal"); + g_signal_emit_by_name (self, NM_AUTH_MANAGER_SIGNAL_CHANGED); +} + +static void +_log_name_owner (NMAuthManager *self, char **out_name_owner) +{ + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + char *name_owner; + + name_owner = g_dbus_proxy_get_name_owner (priv->proxy); + if (name_owner) + _LOGD ("dbus name owner: '%s'", name_owner); + else + _LOGD ("dbus name owner: none"); + + if (out_name_owner) + *out_name_owner = name_owner; + else + g_free (name_owner); +} + +static void +_dbus_on_name_owner_notify_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + NMAuthManager *self = user_data; + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + char *name_owner; + + g_return_if_fail (priv->proxy == (void *) object); + + _log_name_owner (self, &name_owner); + + if (!name_owner) { + /* when the name disappears, we also want to raise a emit signal. + * When it appears, we raise one already. */ + _emit_changed_signal (self); + } + + g_free (name_owner); +} + +static void +_dbus_on_g_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMAuthManager *self = user_data; + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + + g_return_if_fail (priv->proxy == proxy); + + _LOGD ("dbus signal: \"%s\"", signal_name ? signal_name : "(null)"); + + if (g_strcmp0 (signal_name, "Changed") == 0) + _emit_changed_signal (self); +} + +static void +_dbus_new_proxy_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NMAuthManager **p_self = user_data; + NMAuthManager *self = NULL; + NMAuthManagerPrivate *priv; + GError *error = NULL; + GDBusProxy *proxy; + CheckAuthData *data; + + proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (!*p_self) { + _LOGD ("_dbus_new_proxy_cb(): manager destroyed before callback finished. Abort"); + g_clear_object (&proxy); + g_clear_error (&error); + g_free (p_self); + return; + } + self = *p_self; + g_object_remove_weak_pointer (G_OBJECT (self), (void **)p_self); + g_free (p_self); + + priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + + g_return_if_fail (priv->new_proxy_cancellable); + g_return_if_fail (!priv->proxy); + + g_clear_object (&priv->new_proxy_cancellable); + + priv->queued_calls = g_slist_reverse (priv->queued_calls); + + priv->proxy = proxy; + if (!priv->proxy) { + _LOGE ("could not get polkit proxy: %s", error->message); + g_clear_error (&error); + + while (priv->queued_calls) { + data = priv->queued_calls->data; + priv->queued_calls = g_slist_remove (priv->queued_calls, data); + + _call_check_authorization_complete_with_error (data, "error creating DBUS proxy"); + } + return; + } + + g_signal_connect (priv->proxy, + "notify::g-name-owner", + G_CALLBACK (_dbus_on_name_owner_notify_cb), + self); + g_signal_connect (priv->proxy, + "g-signal", + G_CALLBACK (_dbus_on_g_signal_cb), + self); + + _log_name_owner (self, NULL); + + while (priv->queued_calls) { + data = priv->queued_calls->data; + priv->queued_calls = g_slist_remove (priv->queued_calls, data); + _LOGD ("call[%u]: CheckAuthorization invoke now", data->call_id); + _call_check_authorization (data); + } + _emit_changed_signal (self); +} + +#endif + +/*****************************************************************************/ + +NMAuthManager * +nm_auth_manager_get () +{ + g_return_val_if_fail (_instance, NULL); + + return _instance; +} + +NMAuthManager * +nm_auth_manager_setup (gboolean polkit_enabled) +{ + NMAuthManager *self; + + g_return_val_if_fail (!_instance, _instance); + + self = g_object_new (NM_TYPE_AUTH_MANAGER, + NM_AUTH_MANAGER_POLKIT_ENABLED, polkit_enabled, + NULL); + _LOGD ("set instance"); + + return (_instance = self); +} + +/*****************************************************************************/ + +static void +get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_POLKIT_ENABLED: + g_value_set_boolean (value, priv->polkit_enabled); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_POLKIT_ENABLED: + /* construct only */ + priv->polkit_enabled = !!g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_auth_manager_init (NMAuthManager *self) +{ +} + +static void +constructed (GObject *object) +{ + NMAuthManager *self = NM_AUTH_MANAGER (object); + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); + + G_OBJECT_CLASS (nm_auth_manager_parent_class)->constructed (object); + +#if WITH_POLKIT + _LOGD ("create auth-manager: polkit %s", priv->polkit_enabled ? "enabled" : "disabled"); + + if (priv->polkit_enabled) { + NMAuthManager **p_self; + + priv->new_proxy_cancellable = g_cancellable_new (); + p_self = g_new (NMAuthManager *, 1); + *p_self = self; + g_object_add_weak_pointer (G_OBJECT (self), (void **) p_self); + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + POLKIT_SERVICE, + POLKIT_OBJECT_PATH, + POLKIT_INTERFACE, + priv->new_proxy_cancellable, + _dbus_new_proxy_cb, + p_self); + } +#else + if (priv->polkit_enabled) + _LOGW ("create auth-manager: polkit disabled at compile time. All authentication requests will fail"); + else + _LOGD ("create auth-manager: polkit disabled at compile time"); +#endif +} + + +static void +dispose (GObject *object) +{ + NMAuthManager* self = NM_AUTH_MANAGER (object); +#if WITH_POLKIT + NMAuthManagerPrivate *priv = NM_AUTH_MANAGER_GET_PRIVATE (self); +#endif + + _LOGD ("dispose"); + +#if WITH_POLKIT + /* since we take a reference for each queued call, we don't expect to have any queued calls in dispose() */ + g_assert (!priv->queued_calls); + + if (priv->new_proxy_cancellable) { + g_cancellable_cancel (priv->new_proxy_cancellable); + g_clear_object (&priv->new_proxy_cancellable); + } + + if (priv->proxy) { + g_signal_handlers_disconnect_by_func (priv->proxy, _dbus_on_name_owner_notify_cb, self); + g_signal_handlers_disconnect_by_func (priv->proxy, _dbus_on_g_signal_cb, self); + g_clear_object (&priv->proxy); + } +#endif + + G_OBJECT_CLASS (nm_auth_manager_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMAuthManager* self = NM_AUTH_MANAGER (object); + + G_OBJECT_CLASS (nm_auth_manager_parent_class)->finalize (object); + + if (self == _instance) { + _instance = NULL; + _LOGD ("unset instance"); + } +} + +static void +nm_auth_manager_class_init (NMAuthManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMAuthManagerPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + + g_object_class_install_property + (object_class, PROP_POLKIT_ENABLED, + g_param_spec_boolean (NM_AUTH_MANAGER_POLKIT_ENABLED, "", "", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + signals[CHANGED_SIGNAL] = g_signal_new (NM_AUTH_MANAGER_SIGNAL_CHANGED, + NM_TYPE_AUTH_MANAGER, + G_SIGNAL_RUN_LAST, + 0, /* class offset */ + NULL, /* accumulator */ + NULL, /* accumulator data */ + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + +} + diff --git a/src/nm-auth-manager.h b/src/nm-auth-manager.h new file mode 100644 index 00000000..cc3b5d3c --- /dev/null +++ b/src/nm-auth-manager.h @@ -0,0 +1,78 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#ifndef NM_AUTH_MANAGER_H +#define NM_AUTH_MANAGER_H + +#include + +#include "nm-auth-subject.h" + +G_BEGIN_DECLS + + +#define NM_TYPE_AUTH_MANAGER (nm_auth_manager_get_type ()) +#define NM_AUTH_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUTH_MANAGER, NMAuthManager)) +#define NM_AUTH_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AUTH_MANAGER, NMAuthManagerClass)) +#define NM_IS_AUTH_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AUTH_MANAGER)) +#define NM_IS_AUTH_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AUTH_MANAGER)) +#define NM_AUTH_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AUTH_MANAGER, NMAuthManagerClass)) + + +#define NM_AUTH_MANAGER_POLKIT_ENABLED "polkit-enabled" + +#define NM_AUTH_MANAGER_SIGNAL_CHANGED "changed" + +typedef struct { + GObject parent; +} NMAuthManager; + +typedef struct { + GObjectClass parent; +} NMAuthManagerClass; + +GType nm_auth_manager_get_type (void); + +NMAuthManager *nm_auth_manager_setup (gboolean polkit_enabled); +NMAuthManager *nm_auth_manager_get (void); + +gboolean nm_auth_manager_get_polkit_enabled (NMAuthManager *self); + +#if WITH_POLKIT + +void nm_auth_manager_polkit_authority_check_authorization (NMAuthManager *self, + NMAuthSubject *subject, + const char *action_id, + gboolean allow_user_interaction, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_auth_manager_polkit_authority_check_authorization_finish (NMAuthManager *self, + GAsyncResult *res, + gboolean *out_is_authorized, + gboolean *out_is_challenge, + GError **error); + +#endif + +G_END_DECLS + +#endif /* NM_AUTH_MANAGER_H */ + diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c index e770af49..209f98e1 100644 --- a/src/nm-auth-subject.c +++ b/src/nm-auth-subject.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013 - 2014 Red Hat, Inc. */ /** @@ -26,108 +26,212 @@ * makes requests, like process identifier and user UID. */ -#include -#include -#include -#include -#include - -#if WITH_POLKIT -#include -#endif +#include "config.h" #include "nm-auth-subject.h" + +#include +#include +#include + #include "nm-dbus-manager.h" +#include "nm-enum-types.h" +#include "nm-glib-compat.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, + PROP_UNIX_PROCESS_DBUS_SENDER, + PROP_UNIX_PROCESS_PID, + PROP_UNIX_PROCESS_UID, + + PROP_LAST, +}; + typedef struct { - gulong pid; - gulong uid; - char *dbus_sender; + NMAuthSubjectType subject_type; + struct { + gulong pid; + gulong uid; + guint64 start_time; + char *dbus_sender; + } unix_process; +} NMAuthSubjectPrivate; + +/**************************************************************/ + +#define CHECK_SUBJECT(self, error_value) \ + NMAuthSubjectPrivate *priv; \ + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (self), error_value); \ + priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); \ + +#define CHECK_SUBJECT_TYPED(self, expected_subject_type, error_value) \ + CHECK_SUBJECT (self, error_value); \ + g_return_val_if_fail (priv->subject_type == (expected_subject_type), error_value); + +const char * +nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len) +{ + CHECK_SUBJECT (self, NULL); + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + g_snprintf (buf, buf_len, "unix-process[pid=%lu, uid=%lu, start=%llu]", + (long unsigned) priv->unix_process.pid, + (long unsigned) priv->unix_process.uid, + (long long unsigned) priv->unix_process.start_time); + break; + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + g_strlcat (buf, "internal", buf_len); + break; + default: + g_strlcat (buf, "invalid", buf_len); + break; + } + return buf; +} #if WITH_POLKIT - PolkitSubject *pk_subject; + +/* returns a floating variant */ +GVariant * +nm_auth_subject_unix_process_to_polkit_gvariant (NMAuthSubject *self) +{ + GVariantBuilder builder; + GVariant *dict; + GVariant *ret; + CHECK_SUBJECT_TYPED (self, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_add (&builder, "{sv}", "pid", + g_variant_new_uint32 (priv->unix_process.pid)); + g_variant_builder_add (&builder, "{sv}", "start-time", + g_variant_new_uint64 (priv->unix_process.start_time)); + g_variant_builder_add (&builder, "{sv}", "uid", + g_variant_new_int32 (priv->unix_process.uid)); + dict = g_variant_builder_end (&builder); + ret = g_variant_new ("(s@a{sv})", "unix-process", dict); + return ret; +} + #endif -} NMAuthSubjectPrivate; -static NMAuthSubject * -_new_common (DBusGMethodInvocation *context, - DBusConnection *connection, - DBusMessage *message, - gboolean internal) -{ - NMAuthSubject *subject; - NMAuthSubjectPrivate *priv; - NMDBusManager *dbus_mgr; - gboolean success = FALSE; +NMAuthSubjectType +nm_auth_subject_get_subject_type (NMAuthSubject *subject) +{ + CHECK_SUBJECT (subject, NM_AUTH_SUBJECT_TYPE_INVALID); + + return priv->subject_type; +} + +gboolean +nm_auth_subject_is_internal (NMAuthSubject *subject) +{ + return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL; +} + +gboolean +nm_auth_subject_is_unix_process (NMAuthSubject *subject) +{ + return nm_auth_subject_get_subject_type (subject) == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; +} - g_return_val_if_fail (context || (connection && message) || internal, NULL); - if (internal) - g_return_val_if_fail (context == NULL && connection == NULL && message == NULL, NULL); +gulong +nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); - subject = NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, NULL)); - priv = NM_AUTH_SUBJECT_GET_PRIVATE (subject); + return priv->unix_process.pid; +} - dbus_mgr = nm_dbus_manager_get (); +gulong +nm_auth_subject_get_unix_process_uid (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, G_MAXULONG); - if (internal) { - priv->uid = 0; - priv->pid = 0; - return subject; - } + return priv->unix_process.uid; +} + +const char * +nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject) +{ + CHECK_SUBJECT_TYPED (subject, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, NULL); + + return priv->unix_process.dbus_sender; +} + +/**************************************************************/ + +static NMAuthSubject * +_new_unix_process (DBusGMethodInvocation *context, + DBusConnection *connection, + DBusMessage *message) +{ + NMAuthSubject *self; + gboolean success = FALSE; + gulong pid = 0, uid = 0; + char *dbus_sender = NULL; + + g_return_val_if_fail (context || (connection && message), NULL); if (context) { - success = nm_dbus_manager_get_caller_info (dbus_mgr, + success = nm_dbus_manager_get_caller_info (nm_dbus_manager_get (), context, - &priv->dbus_sender, - &priv->uid, - &priv->pid); + &dbus_sender, + &uid, + &pid); } else if (message) { - success = nm_dbus_manager_get_caller_info_from_message (dbus_mgr, + success = nm_dbus_manager_get_caller_info_from_message (nm_dbus_manager_get (), connection, message, - &priv->dbus_sender, - &priv->uid, - &priv->pid); + &dbus_sender, + &uid, + &pid); } else g_assert_not_reached (); - if (!success) { - g_object_unref (subject); + if (!success) return NULL; - } - g_assert (priv->dbus_sender); - g_assert_cmpuint (priv->pid, !=, 0); - -#if WITH_POLKIT - /* FIXME: should we use polkit_unix_session_new() to store the session ID - * of a short-lived process, so that the process can exit but we can still - * ask that user for authorization? - */ - priv->pk_subject = polkit_unix_process_new_for_owner (priv->pid, 0, priv->uid); - if (!priv->pk_subject) - return NULL; -#endif - - return subject; + g_return_val_if_fail (dbus_sender && *dbus_sender, NULL); + /* polkit glib library stores uid and pid as gint. There might be some + * pitfalls if the id ever happens to be larger then that. Just assert against + * it here. */ + g_return_val_if_fail (uid <= MIN (G_MAXINT, G_MAXINT32), NULL); + g_return_val_if_fail (pid > 0 && pid <= MIN (G_MAXINT, G_MAXINT32), NULL); + + self = NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, + NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, dbus_sender, + NM_AUTH_SUBJECT_UNIX_PROCESS_PID, (gulong) pid, + NM_AUTH_SUBJECT_UNIX_PROCESS_UID, (gulong) uid, + NULL)); + + if (NM_AUTH_SUBJECT_GET_PRIVATE (self)->subject_type != NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS) { + /* this most likely happened because the process is gone (start_time==0). + * Either that is not assert-worthy, or constructed() already asserted. + * Just return NULL. */ + g_clear_object (&self); + } + return self; } - NMAuthSubject * -nm_auth_subject_new_from_context (DBusGMethodInvocation *context) +nm_auth_subject_new_unix_process_from_context (DBusGMethodInvocation *context) { - return _new_common (context, NULL, NULL, FALSE); + return _new_unix_process (context, NULL, NULL); } NMAuthSubject * -nm_auth_subject_new_from_message (DBusConnection *connection, - DBusMessage *message) +nm_auth_subject_new_unix_process_from_message (DBusConnection *connection, + DBusMessage *message) { - return _new_common (NULL, connection, message, FALSE); + return _new_unix_process (NULL, connection, message); } /** @@ -140,53 +244,135 @@ nm_auth_subject_new_from_message (DBusConnection *connection, NMAuthSubject * nm_auth_subject_new_internal (void) { - return _new_common (NULL, NULL, NULL, TRUE); + return NM_AUTH_SUBJECT (g_object_new (NM_TYPE_AUTH_SUBJECT, + NM_AUTH_SUBJECT_SUBJECT_TYPE, NM_AUTH_SUBJECT_TYPE_INTERNAL, + NULL)); } /**************************************************************/ -gulong -nm_auth_subject_get_uid (NMAuthSubject *subject) +static void +get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->uid; -} + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); -gulong -nm_auth_subject_get_pid (NMAuthSubject *subject) -{ - return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->pid; + switch (prop_id) { + case PROP_SUBJECT_TYPE: + g_value_set_enum (value, priv->subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + g_value_set_string (value, priv->unix_process.dbus_sender); + break; + case PROP_UNIX_PROCESS_PID: + g_value_set_ulong (value, priv->unix_process.pid); + break; + case PROP_UNIX_PROCESS_UID: + g_value_set_ulong (value, priv->unix_process.uid); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -const char * -nm_auth_subject_get_dbus_sender (NMAuthSubject *subject) +static void +set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->dbus_sender; + NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); + NMAuthSubjectType subject_type; + const char *str; + gulong id; + + /* all properties are construct-only */ + switch (prop_id) { + case PROP_SUBJECT_TYPE: + subject_type = g_value_get_enum (value); + g_return_if_fail (subject_type != NM_AUTH_SUBJECT_TYPE_INVALID); + priv->subject_type |= subject_type; + g_return_if_fail (priv->subject_type == subject_type); + break; + case PROP_UNIX_PROCESS_DBUS_SENDER: + if ((str = g_value_get_string (value))) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.dbus_sender = g_strdup (str); + } + break; + case PROP_UNIX_PROCESS_PID: + if ((id = g_value_get_ulong (value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.pid = id; + } + break; + case PROP_UNIX_PROCESS_UID: + if ((id = g_value_get_ulong (value)) != G_MAXULONG) { + priv->subject_type |= NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS; + g_return_if_fail (priv->subject_type == NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS); + priv->unix_process.uid = id; + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } -gboolean -nm_auth_subject_get_internal (NMAuthSubject *subject) +static void +_clear_private (NMAuthSubjectPrivate *priv) { - /* internal requests will have no dbus sender */ - return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->dbus_sender ? FALSE : TRUE; + priv->subject_type = NM_AUTH_SUBJECT_TYPE_INVALID; + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = G_MAXULONG; + g_clear_pointer (&priv->unix_process.dbus_sender, g_free); } -#if WITH_POLKIT -PolkitSubject * -nm_auth_subject_get_polkit_subject (NMAuthSubject *subject) +static void +nm_auth_subject_init (NMAuthSubject *self) { - return NM_AUTH_SUBJECT_GET_PRIVATE (subject)->pk_subject; + _clear_private (NM_AUTH_SUBJECT_GET_PRIVATE (self)); } -#endif - -/******************************************************************/ static void -nm_auth_subject_init (NMAuthSubject *self) +constructed (GObject *object) { + NMAuthSubject *self = NM_AUTH_SUBJECT (object); NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (self); - priv->pid = G_MAXULONG; - priv->uid = G_MAXULONG; + /* validate that the created instance. */ + + switch (priv->subject_type) { + case NM_AUTH_SUBJECT_TYPE_INTERNAL: + priv->unix_process.pid = G_MAXULONG; + priv->unix_process.uid = 0; /* internal uses 'root' user */ + return; + case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: + /* Ensure pid and uid to be representable as int32. + * DBUS treats them as uint32, polkit library as gint. */ + if (priv->unix_process.pid > MIN (G_MAXINT, G_MAXINT32)) + break; + if (priv->unix_process.uid > MIN (G_MAXINT, G_MAXINT32)) { + /* for uid==-1, libpolkit-gobject-1 detects the user based on the process id. + * Don't bother and require the user id as parameter. */ + break; + } + if (!priv->unix_process.dbus_sender || !*priv->unix_process.dbus_sender) + break; + + priv->unix_process.start_time = nm_utils_get_start_time_for_pid (priv->unix_process.pid); + + if (!priv->unix_process.start_time) { + /* could not detect the process start time. The subject is invalid, but don't + * assert against it. */ + _clear_private (priv); + } + return; + default: + break; + } + + _clear_private (priv); + g_return_if_reached (); } static void @@ -194,12 +380,7 @@ finalize (GObject *object) { NMAuthSubjectPrivate *priv = NM_AUTH_SUBJECT_GET_PRIVATE (object); - g_free (priv->dbus_sender); - -#if WITH_POLKIT - if (priv->pk_subject) - g_object_unref (priv->pk_subject); -#endif + _clear_private (priv); G_OBJECT_CLASS (nm_auth_subject_parent_class)->finalize (object); } @@ -212,5 +393,42 @@ nm_auth_subject_class_init (NMAuthSubjectClass *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; + object_class->constructed = constructed; object_class->finalize = finalize; + + g_object_class_install_property + (object_class, PROP_SUBJECT_TYPE, + g_param_spec_enum (NM_AUTH_SUBJECT_SUBJECT_TYPE, "", "", + NM_TYPE_AUTH_SUBJECT_TYPE, + NM_AUTH_SUBJECT_TYPE_INVALID, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_DBUS_SENDER, + g_param_spec_string (NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_PID, + g_param_spec_ulong (NM_AUTH_SUBJECT_UNIX_PROCESS_PID, "", "", + 0, G_MAXULONG, G_MAXULONG, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_UNIX_PROCESS_UID, + g_param_spec_ulong (NM_AUTH_SUBJECT_UNIX_PROCESS_UID, "", "", + 0, G_MAXULONG, G_MAXULONG, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + } diff --git a/src/nm-auth-subject.h b/src/nm-auth-subject.h index 06359890..cc004fa9 100644 --- a/src/nm-auth-subject.h +++ b/src/nm-auth-subject.h @@ -18,8 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_AUTH_SUBJECT_H -#define NM_AUTH_SUBJECT_H +#ifndef __NETWORKMANAGER_AUTH_SUBJECT_H__ +#define __NETWORKMANAGER_AUTH_SUBJECT_H__ #include #include @@ -27,9 +27,7 @@ #include #include -#if WITH_POLKIT -#include -#endif +#include "nm-types.h" #define NM_TYPE_AUTH_SUBJECT (nm_auth_subject_get_type ()) #define NM_AUTH_SUBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubject)) @@ -38,33 +36,56 @@ #define NM_IS_AUTH_SUBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AUTH_SUBJECT)) #define NM_AUTH_SUBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AUTH_SUBJECT, NMAuthSubjectClass)) -typedef struct { +typedef enum { + NM_AUTH_SUBJECT_TYPE_INVALID = 0, + NM_AUTH_SUBJECT_TYPE_INTERNAL = 1, + NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS = 2, +} NMAuthSubjectType; + +#define NM_AUTH_SUBJECT_SUBJECT_TYPE "subject-type" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_DBUS_SENDER "unix-process-dbus-sender" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_PID "unix-process-pid" +#define NM_AUTH_SUBJECT_UNIX_PROCESS_UID "unix-process-uid" + +struct _NMAuthSubject { GObject parent; -} NMAuthSubject; +}; typedef struct { GObjectClass parent; - } NMAuthSubjectClass; GType nm_auth_subject_get_type (void); -NMAuthSubject *nm_auth_subject_new_from_context (DBusGMethodInvocation *context); +NMAuthSubject *nm_auth_subject_new_internal (void); + +NMAuthSubject *nm_auth_subject_new_unix_process_from_context (DBusGMethodInvocation *context); -NMAuthSubject *nm_auth_subject_new_from_message (DBusConnection *connection, DBusMessage *message); +NMAuthSubject *nm_auth_subject_new_unix_process_from_message (DBusConnection *connection, DBusMessage *message); -NMAuthSubject *nm_auth_subject_new_internal (void); -gulong nm_auth_subject_get_uid (NMAuthSubject *subject); +NMAuthSubjectType nm_auth_subject_get_subject_type (NMAuthSubject *subject); -gulong nm_auth_subject_get_pid (NMAuthSubject *subject); -const char *nm_auth_subject_get_dbus_sender (NMAuthSubject *subject); +gboolean nm_auth_subject_is_internal (NMAuthSubject *subject); -gboolean nm_auth_subject_get_internal (NMAuthSubject *subject); + +gboolean nm_auth_subject_is_unix_process (NMAuthSubject *subject); + +gulong nm_auth_subject_get_unix_process_pid (NMAuthSubject *subject); + +const char *nm_auth_subject_get_unix_process_dbus_sender (NMAuthSubject *subject); + + +gulong nm_auth_subject_get_unix_process_uid (NMAuthSubject *subject); + + +const char *nm_auth_subject_to_string (NMAuthSubject *self, char *buf, gsize buf_len); #if WITH_POLKIT -PolkitSubject *nm_auth_subject_get_polkit_subject (NMAuthSubject *subject); + +GVariant * nm_auth_subject_unix_process_to_polkit_gvariant (NMAuthSubject *self); + #endif -#endif /* NM_AUTH_SUBJECT_H */ +#endif /* __NETWORKMANAGER_AUTH_SUBJECT_H__ */ diff --git a/src/nm-auth-utils.c b/src/nm-auth-utils.c new file mode 100644 index 00000000..9ace1629 --- /dev/null +++ b/src/nm-auth-utils.c @@ -0,0 +1,480 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include + +#include "gsystem-local-alloc.h" +#include "nm-setting-connection.h" +#include "nm-auth-utils.h" +#include "nm-logging.h" +#include "nm-dbus-manager.h" +#include "nm-auth-subject.h" +#include "nm-auth-manager.h" +#include "nm-session-monitor.h" + +struct NMAuthChain { + guint32 refcount; + GSList *calls; + GHashTable *data; + + DBusGMethodInvocation *context; + NMAuthSubject *subject; + GError *error; + + guint idle_id; + + NMAuthChainResultFunc done_func; + gpointer user_data; +}; + +typedef struct { + NMAuthChain *chain; + GCancellable *cancellable; + char *permission; + guint call_idle_id; +} AuthCall; + +typedef struct { + gpointer data; + GDestroyNotify destroy; +} ChainData; + +static void +free_data (gpointer data) +{ + ChainData *tmp = data; + + if (tmp->destroy) + tmp->destroy (tmp->data); + memset (tmp, 0, sizeof (ChainData)); + g_free (tmp); +} + +static gboolean +auth_chain_finish (gpointer user_data) +{ + NMAuthChain *self = user_data; + + self->idle_id = 0; + + /* Ensure we say alive across the callback */ + self->refcount++; + self->done_func (self, self->error, self->context, self->user_data); + nm_auth_chain_unref (self); + return FALSE; +} + +/* Creates the NMAuthSubject automatically */ +NMAuthChain * +nm_auth_chain_new_context (DBusGMethodInvocation *context, + NMAuthChainResultFunc done_func, + gpointer user_data) +{ + NMAuthSubject *subject; + NMAuthChain *chain; + + g_return_val_if_fail (context != NULL, NULL); + + subject = nm_auth_subject_new_unix_process_from_context (context); + if (!subject) + return NULL; + + chain = nm_auth_chain_new_subject (subject, + context, + done_func, + user_data); + g_object_unref (subject); + return chain; +} + +/* Requires an NMAuthSubject */ +NMAuthChain * +nm_auth_chain_new_subject (NMAuthSubject *subject, + DBusGMethodInvocation *context, + NMAuthChainResultFunc done_func, + gpointer user_data) +{ + NMAuthChain *self; + + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); + g_return_val_if_fail (nm_auth_subject_is_unix_process (subject) || nm_auth_subject_is_internal (subject), NULL); + + self = g_malloc0 (sizeof (NMAuthChain)); + self->refcount = 1; + self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_data); + self->done_func = done_func; + self->user_data = user_data; + self->context = context; + self->subject = g_object_ref (subject); + + return self; +} + +gpointer +nm_auth_chain_get_data (NMAuthChain *self, const char *tag) +{ + ChainData *tmp; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (tag != NULL, NULL); + + tmp = g_hash_table_lookup (self->data, tag); + return tmp ? tmp->data : NULL; +} + +/** + * nm_auth_chain_steal_data: + * @self: A #NMAuthChain. + * @tag: A "tag" uniquely identifying the data to steal. + * + * Removes the datum assocated with @tag from the chain's data associations, + * without invoking the association's destroy handler. The caller assumes + * ownership over the returned value. + * + * Returns: the datum originally associated with @tag + */ +gpointer +nm_auth_chain_steal_data (NMAuthChain *self, const char *tag) +{ + ChainData *tmp; + gpointer value = NULL; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (tag != NULL, NULL); + + tmp = g_hash_table_lookup (self->data, tag); + if (tmp) { + g_hash_table_steal (self->data, tag); + value = tmp->data; + /* Make sure the destroy handler isn't called when freeing */ + tmp->destroy = NULL; + free_data (tmp); + } + return value; +} + +void +nm_auth_chain_set_data (NMAuthChain *self, + const char *tag, + gpointer data, + GDestroyNotify data_destroy) +{ + ChainData *tmp; + + g_return_if_fail (self != NULL); + g_return_if_fail (tag != NULL); + + if (data == NULL) + g_hash_table_remove (self->data, tag); + else { + tmp = g_malloc0 (sizeof (ChainData)); + tmp->data = data; + tmp->destroy = data_destroy; + + g_hash_table_insert (self->data, g_strdup (tag), tmp); + } +} + +gulong +nm_auth_chain_get_data_ulong (NMAuthChain *self, const char *tag) +{ + gulong *ptr; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (tag != NULL, 0); + + ptr = nm_auth_chain_get_data (self, tag); + return *ptr; +} + + +void +nm_auth_chain_set_data_ulong (NMAuthChain *self, + const char *tag, + gulong data) +{ + gulong *ptr; + + g_return_if_fail (self != NULL); + g_return_if_fail (tag != NULL); + + ptr = g_malloc (sizeof (*ptr)); + *ptr = data; + nm_auth_chain_set_data (self, tag, ptr, g_free); +} + +NMAuthCallResult +nm_auth_chain_get_result (NMAuthChain *self, const char *permission) +{ + g_return_val_if_fail (self != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); + g_return_val_if_fail (permission != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); + + return GPOINTER_TO_UINT (nm_auth_chain_get_data (self, permission)); +} + +static void +nm_auth_chain_check_done (NMAuthChain *self) +{ + g_return_if_fail (self != NULL); + + if (g_slist_length (self->calls) == 0) { + g_assert (self->idle_id == 0); + self->idle_id = g_idle_add (auth_chain_finish, self); + } +} + +static void +nm_auth_chain_remove_call (NMAuthChain *self, AuthCall *call) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (call != NULL); + + self->calls = g_slist_remove (self->calls, call); +} + +static AuthCall * +auth_call_new (NMAuthChain *chain, const char *permission) +{ + AuthCall *call; + + call = g_malloc0 (sizeof (AuthCall)); + call->chain = chain; + call->permission = g_strdup (permission); + chain->calls = g_slist_append (chain->calls, call); + return call; +} + +static void +auth_call_free (AuthCall *call) +{ + g_free (call->permission); + g_clear_object (&call->cancellable); + g_free (call); +} + +/* This can get used from scheduled idles, hence the boolean return */ +static gboolean +auth_call_complete (AuthCall *call) +{ + nm_auth_chain_remove_call (call->chain, call); + nm_auth_chain_check_done (call->chain); + auth_call_free (call); + return FALSE; +} + +static void +auth_call_cancel (gpointer user_data) +{ + AuthCall *call = user_data; + + if (call->cancellable) { + /* we don't free call immediately. Instead we cancel the async operation + * and set cancellable to NULL. pk_call_cb() will check for this and + * do the final cleanup. */ + g_cancellable_cancel (call->cancellable); + g_clear_object (&call->cancellable); + } else { + g_source_remove (call->call_idle_id); + auth_call_free (call); + } +} + +#if WITH_POLKIT +static void +pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + AuthCall *call = user_data; + GError *error = NULL; + gboolean is_authorized, is_challenge; + + nm_auth_manager_polkit_authority_check_authorization_finish (NM_AUTH_MANAGER (object), + result, + &is_authorized, + &is_challenge, + &error); + + /* If the call is already canceled do nothing */ + if (!call->cancellable) { + nm_log_dbg (LOGD_CORE, "callback already cancelled"); + g_clear_error (&error); + auth_call_free (call); + return; + } + + if (error) { + nm_log_warn (LOGD_CORE, "error requesting auth for %s: (%d) %s", + call->permission, error->code, error->message); + + if (!call->chain->error) { + call->chain->error = error; + error = NULL; + } else + g_clear_error (&error); + } else { + guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; + + if (is_authorized) { + /* Caller has the permission */ + call_result = NM_AUTH_CALL_RESULT_YES; + } else if (is_challenge) { + /* Caller could authenticate to get the permission */ + call_result = NM_AUTH_CALL_RESULT_AUTH; + } else + call_result = NM_AUTH_CALL_RESULT_NO; + + nm_auth_chain_set_data (call->chain, call->permission, GUINT_TO_POINTER (call_result), NULL); + } + + auth_call_complete (call); +} +#endif + +void +nm_auth_chain_add_call (NMAuthChain *self, + const char *permission, + gboolean allow_interaction) +{ + AuthCall *call; + NMAuthManager *auth_manager = nm_auth_manager_get (); + + g_return_if_fail (self != NULL); + g_return_if_fail (permission && *permission); + g_return_if_fail (self->subject); + g_return_if_fail (nm_auth_subject_is_unix_process (self->subject) || nm_auth_subject_is_internal (self->subject)); + + call = auth_call_new (self, permission); + + if ( nm_auth_subject_is_internal (self->subject) + || nm_auth_subject_get_unix_process_uid (self->subject) == 0 + || !nm_auth_manager_get_polkit_enabled (auth_manager)) { + /* Root user or non-polkit always gets the permission */ + nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); + call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); + } else { + /* Non-root always gets authenticated when using polkit */ +#if WITH_POLKIT + call->cancellable = g_cancellable_new (); + nm_auth_manager_polkit_authority_check_authorization (auth_manager, + self->subject, + permission, + allow_interaction, + call->cancellable, + pk_call_cb, + call); +#else + if (!call->chain->error) { + call->chain->error = g_error_new_literal (DBUS_GERROR, + DBUS_GERROR_FAILED, + "Polkit support is disabled at compile time"); + } + call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); +#endif + } +} + +void +nm_auth_chain_unref (NMAuthChain *self) +{ + g_return_if_fail (self != NULL); + + self->refcount--; + if (self->refcount > 0) + return; + + if (self->idle_id) + g_source_remove (self->idle_id); + + g_object_unref (self->subject); + + g_slist_free_full (self->calls, auth_call_cancel); + + g_clear_error (&self->error); + g_hash_table_destroy (self->data); + + memset (self, 0, sizeof (NMAuthChain)); + g_free (self); +} + +/************ utils **************/ + +gboolean +nm_auth_is_subject_in_acl (NMConnection *connection, + NMSessionMonitor *smon, + NMAuthSubject *subject, + char **out_error_desc) +{ + NMSettingConnection *s_con; + const char *user = NULL; + GError *local = NULL; + gulong uid; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (smon != NULL, FALSE); + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), FALSE); + g_return_val_if_fail (nm_auth_subject_is_internal (subject) || nm_auth_subject_is_unix_process (subject), FALSE); + + if (nm_auth_subject_is_internal (subject)) + return TRUE; + + uid = nm_auth_subject_get_unix_process_uid (subject); + + /* Root gets a free pass */ + if (0 == uid) + return TRUE; + + /* Reject the request if the request comes from no session at all */ + if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { + if (out_error_desc) { + *out_error_desc = g_strdup_printf ("No session found for uid %lu (%s)", + uid, + local && local->message ? local->message : "unknown"); + } + g_clear_error (&local); + return FALSE; + } + + if (!user) { + if (out_error_desc) + *out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid); + return FALSE; + } + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + /* This can only happen when called from AddAndActivate, so we know + * the user will be authorized when the connection is completed. + */ + return TRUE; + } + + /* Match the username returned by the session check to a user in the ACL */ + if (!nm_setting_connection_permissions_user_allowed (s_con, user)) { + if (out_error_desc) + *out_error_desc = g_strdup_printf ("uid %lu has no permission to perform this operation", uid); + return FALSE; + } + + return TRUE; +} + + diff --git a/src/nm-auth-utils.h b/src/nm-auth-utils.h new file mode 100644 index 00000000..2ab026d0 --- /dev/null +++ b/src/nm-auth-utils.h @@ -0,0 +1,97 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_MANAGER_AUTH_H__ +#define __NETWORKMANAGER_MANAGER_AUTH_H__ + +#include +#include + +#include +#include "nm-types.h" + +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" + + +typedef struct NMAuthChain NMAuthChain; + +typedef enum { + NM_AUTH_CALL_RESULT_UNKNOWN, + NM_AUTH_CALL_RESULT_YES, + NM_AUTH_CALL_RESULT_AUTH, + NM_AUTH_CALL_RESULT_NO, +} NMAuthCallResult; + +typedef void (*NMAuthChainResultFunc) (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data); + +NMAuthChain *nm_auth_chain_new_context (DBusGMethodInvocation *context, + NMAuthChainResultFunc done_func, + gpointer user_data); + +NMAuthChain *nm_auth_chain_new_subject (NMAuthSubject *subject, + DBusGMethodInvocation *context, + NMAuthChainResultFunc done_func, + gpointer user_data); + +gpointer nm_auth_chain_get_data (NMAuthChain *chain, const char *tag); + +gpointer nm_auth_chain_steal_data (NMAuthChain *chain, const char *tag); + +void nm_auth_chain_set_data (NMAuthChain *chain, + const char *tag, + gpointer data, + GDestroyNotify data_destroy); + +void nm_auth_chain_set_data_ulong (NMAuthChain *chain, + const char *tag, + gulong data); + +gulong nm_auth_chain_get_data_ulong (NMAuthChain *chain, const char *tag); + +NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain, + const char *permission); + +void nm_auth_chain_add_call (NMAuthChain *chain, + const char *permission, + gboolean allow_interaction); + +void nm_auth_chain_unref (NMAuthChain *chain); + +/* Caller must free returned error description */ +gboolean nm_auth_is_subject_in_acl (NMConnection *connection, + NMSessionMonitor *smon, + NMAuthSubject *subect, + char **out_error_desc); + +#endif /* __NETWORKMANAGER_MANAGER_AUTH_H__ */ + diff --git a/src/nm-config.c b/src/nm-config.c new file mode 100644 index 00000000..e8cb0864 --- /dev/null +++ b/src/nm-config.c @@ -0,0 +1,675 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2013 Thomas Bechtold + */ + +#include "config.h" + +#include +#include + +#include "nm-config.h" +#include "nm-logging.h" +#include "nm-utils.h" +#include "nm-glib-compat.h" +#include "nm-device.h" + +#include +#include + +#define NM_DEFAULT_SYSTEM_CONF_FILE NMCONFDIR "/NetworkManager.conf" +#define NM_DEFAULT_SYSTEM_CONF_DIR NMCONFDIR "/conf.d" +#define NM_OLD_SYSTEM_CONF_FILE NMCONFDIR "/nm-system-settings.conf" +#define NM_NO_AUTO_DEFAULT_STATE_FILE NMSTATEDIR "/no-auto-default.state" + +typedef struct { + char *nm_conf_path; + char *config_dir; + char *config_description; + char *no_auto_default_file; + GKeyFile *keyfile; + + char **plugins; + gboolean monitor_connection_files; + gboolean auth_polkit; + char *dhcp_client; + char *dns_mode; + + char *log_level; + char *log_domains; + + char *debug; + + char *connectivity_uri; + gint connectivity_interval; + char *connectivity_response; + + char **no_auto_default; + char **ignore_carrier; + + gboolean configure_and_quit; +} NMConfigPrivate; + +static NMConfig *singleton = NULL; + +G_DEFINE_TYPE (NMConfig, nm_config, G_TYPE_OBJECT) + +#define NM_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CONFIG, NMConfigPrivate)) + +/************************************************************************/ + +static gboolean +_get_bool_value (GKeyFile *keyfile, + const char *section, + const char *key, + gboolean default_value) +{ + gboolean value = default_value; + char *str; + + g_return_val_if_fail (keyfile != NULL, default_value); + g_return_val_if_fail (section != NULL, default_value); + g_return_val_if_fail (key != NULL, default_value); + + str = g_key_file_get_value (keyfile, section, key, NULL); + if (!str) + return default_value; + + g_strstrip (str); + if (str[0]) { + if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1")) + value = TRUE; + else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0")) + value = FALSE; + else { + nm_log_warn (LOGD_CORE, "Unrecognized value for %s.%s: '%s'. Assuming '%s'", + section, key, str, default_value ? "true" : "false"); + } + } + + g_free (str); + return value; +} + +/************************************************************************/ + +const char * +nm_config_get_path (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->nm_conf_path; +} + +const char * +nm_config_get_description (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->config_description; +} + +const char ** +nm_config_get_plugins (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return (const char **) NM_CONFIG_GET_PRIVATE (config)->plugins; +} + +gboolean +nm_config_get_monitor_connection_files (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, FALSE); + + return NM_CONFIG_GET_PRIVATE (config)->monitor_connection_files; +} + +gboolean +nm_config_get_auth_polkit (NMConfig *config) +{ + g_return_val_if_fail (NM_IS_CONFIG (config), NM_CONFIG_DEFAULT_AUTH_POLKIT); + + return NM_CONFIG_GET_PRIVATE (config)->auth_polkit; +} + +const char * +nm_config_get_dhcp_client (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->dhcp_client; +} + +const char * +nm_config_get_dns_mode (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->dns_mode; +} + +const char * +nm_config_get_log_level (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->log_level; +} + +const char * +nm_config_get_log_domains (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->log_domains; +} + +const char * +nm_config_get_debug (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->debug; +} + +const char * +nm_config_get_connectivity_uri (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->connectivity_uri; +} + +guint +nm_config_get_connectivity_interval (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, 0); + + /* We store interval as signed internally to track whether it's + * set or not, but report as unsigned to callers. + */ + return MAX (NM_CONFIG_GET_PRIVATE (config)->connectivity_interval, 0); +} + +const char * +nm_config_get_connectivity_response (NMConfig *config) +{ + g_return_val_if_fail (config != NULL, NULL); + + return NM_CONFIG_GET_PRIVATE (config)->connectivity_response; +} + +gboolean +nm_config_get_configure_and_quit (NMConfig *config) +{ + return NM_CONFIG_GET_PRIVATE (config)->configure_and_quit; +} + +char * +nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + return g_key_file_get_string (priv->keyfile, group, key, error); +} + +gboolean +nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GSList *specs = NULL; + int i; + gboolean match; + + if (!priv->ignore_carrier) + return FALSE; + + for (i = 0; priv->ignore_carrier[i]; i++) + specs = g_slist_prepend (specs, priv->ignore_carrier[i]); + + match = nm_device_spec_match_list (device, specs); + + g_slist_free (specs); + return match; +} + +/************************************************************************/ + +static void +merge_no_auto_default_state (NMConfig *config) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GPtrArray *updated; + char **list; + int i, j; + char *data; + + /* If the config already matches everything, we don't need to do anything else. */ + if (priv->no_auto_default && !g_strcmp0 (priv->no_auto_default[0], "*")) + return; + + updated = g_ptr_array_new (); + if (priv->no_auto_default) { + for (i = 0; priv->no_auto_default[i]; i++) + g_ptr_array_add (updated, priv->no_auto_default[i]); + g_free (priv->no_auto_default); + } + + if (g_file_get_contents (priv->no_auto_default_file, &data, NULL, NULL)) { + list = g_strsplit (data, "\n", -1); + for (i = 0; list[i]; i++) { + if (!*list[i]) + continue; + for (j = 0; j < updated->len; j++) { + if (!strcmp (list[i], updated->pdata[j])) + break; + } + if (j == updated->len) + g_ptr_array_add (updated, list[i]); + } + g_free (list); + g_free (data); + } + + g_ptr_array_add (updated, NULL); + priv->no_auto_default = (char **) g_ptr_array_free (updated, FALSE); +} + +gboolean +nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GSList *specs = NULL; + int i; + gboolean match; + + for (i = 0; priv->no_auto_default[i]; i++) + specs = g_slist_prepend (specs, priv->no_auto_default[i]); + + match = nm_device_spec_match_list (device, specs); + + g_slist_free (specs); + return !match; +} + +void +nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + char *current; + GString *updated; + GError *error = NULL; + + if (!nm_config_get_ethernet_can_auto_default (config, device)) + return; + + updated = g_string_new (NULL); + if (g_file_get_contents (priv->no_auto_default_file, ¤t, NULL, NULL)) { + g_string_append (updated, current); + g_free (current); + if (updated->str[updated->len - 1] != '\n') + g_string_append_c (updated, '\n'); + } + + g_string_append (updated, nm_device_get_hw_address (device)); + g_string_append_c (updated, '\n'); + + if (!g_file_set_contents (priv->no_auto_default_file, updated->str, updated->len, &error)) { + nm_log_warn (LOGD_SETTINGS, "Could not update no-auto-default.state file: %s", + error->message); + g_error_free (error); + } + + g_string_free (updated, TRUE); + + merge_no_auto_default_state (config); +} + +/************************************************************************/ + +static char *cli_config_path; +static char *cli_config_dir; +static char *cli_no_auto_default_file; +static char *cli_plugins; +static char *cli_connectivity_uri; +static int cli_connectivity_interval = -1; +static char *cli_connectivity_response; + +static GOptionEntry config_options[] = { + { "config", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_path, N_("Config file location"), N_("/path/to/config.file") }, + { "config-dir", 0, 0, G_OPTION_ARG_FILENAME, &cli_config_dir, N_("Config directory location"), N_("/path/to/config/dir") }, + { "no-auto-default", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &cli_no_auto_default_file, "no-auto-default.state location", NULL }, + { "plugins", 0, 0, G_OPTION_ARG_STRING, &cli_plugins, N_("List of plugins separated by ','"), N_("plugin1,plugin2") }, + + /* These three are hidden for now, and should eventually just go away. */ + { "connectivity-uri", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_uri, N_("An http(s) address for checking internet connectivity"), "http://example.com" }, + { "connectivity-interval", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_INT, &cli_connectivity_interval, N_("The interval between connectivity checks (in seconds)"), "60" }, + { "connectivity-response", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &cli_connectivity_response, N_("The expected start of the response"), N_("Bingo!") }, + {NULL} +}; +GOptionEntry * +nm_config_get_options (void) +{ + return config_options; +} + +/************************************************************************/ + +static gboolean +read_config (NMConfig *config, const char *path, GError **error) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GKeyFile *kf; + char **groups, **keys; + gsize ngroups, nkeys; + int g, k; + + if (g_file_test (path, G_FILE_TEST_EXISTS) == FALSE) { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "file %s not found", path); + return FALSE; + } + + nm_log_dbg (LOGD_SETTINGS, "Reading config file '%s'", path); + + kf = g_key_file_new (); + g_key_file_set_list_separator (kf, ','); + if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, error)) { + g_key_file_free (kf); + return FALSE; + } + + /* Override the current settings with the new ones */ + groups = g_key_file_get_groups (kf, &ngroups); + for (g = 0; groups[g]; g++) { + keys = g_key_file_get_keys (kf, groups[g], &nkeys, NULL); + if (!keys) + continue; + for (k = 0; keys[k]; k++) { + int len = strlen (keys[k]); + if (keys[k][len - 1] == '+') { + char *base_key = g_strndup (keys[k], len - 1); + const char *old_val = g_key_file_get_value (priv->keyfile, groups[g], base_key, NULL); + const char *new_val = g_key_file_get_value (kf, groups[g], keys[k], NULL); + + if (old_val && *old_val) { + char *combined = g_strconcat (old_val, ",", new_val, NULL); + + g_key_file_set_value (priv->keyfile, groups[g], base_key, combined); + g_free (combined); + } else + g_key_file_set_value (priv->keyfile, groups[g], base_key, new_val); + + g_free (base_key); + continue; + } + + g_key_file_set_value (priv->keyfile, groups[g], keys[k], + g_key_file_get_value (kf, groups[g], keys[k], NULL)); + } + } + g_key_file_free (kf); + + return TRUE; +} + +static gboolean +find_base_config (NMConfig *config, GError **error) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + GError *my_error = NULL; + + /* Try a user-specified config file first */ + if (cli_config_path) { + /* Bad user-specific config file path is a hard error */ + if (read_config (config, cli_config_path, error)) { + priv->nm_conf_path = g_strdup (cli_config_path); + return TRUE; + } else + return FALSE; + } + + /* Even though we prefer NetworkManager.conf, we need to check the + * old nm-system-settings.conf first to preserve compat with older + * setups. In package managed systems dropping a NetworkManager.conf + * onto the system would make NM use it instead of nm-system-settings.conf, + * changing behavior during an upgrade. We don't want that. + */ + + /* Try deprecated nm-system-settings.conf first */ + if (read_config (config, NM_OLD_SYSTEM_CONF_FILE, &my_error)) { + priv->nm_conf_path = g_strdup (NM_OLD_SYSTEM_CONF_FILE); + return TRUE; + } + + if (!g_error_matches (my_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { + nm_log_warn (LOGD_CORE, "Old default config file %s invalid: %s\n", + NM_OLD_SYSTEM_CONF_FILE, + my_error->message); + } + g_clear_error (&my_error); + + /* Try the standard config file location next */ + if (read_config (config, NM_DEFAULT_SYSTEM_CONF_FILE, &my_error)) { + priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE); + return TRUE; + } + + if (!g_error_matches (my_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { + nm_log_warn (LOGD_CORE, "Default config file %s invalid: %s\n", + NM_DEFAULT_SYSTEM_CONF_FILE, + my_error->message); + g_propagate_error (error, my_error); + return FALSE; + } + g_clear_error (&my_error); + + /* If for some reason no config file exists, use the default + * config file path. + */ + priv->nm_conf_path = g_strdup (NM_DEFAULT_SYSTEM_CONF_FILE); + nm_log_info (LOGD_CORE, "No config file found or given; using %s\n", + NM_DEFAULT_SYSTEM_CONF_FILE); + return TRUE; +} + +/************************************************************************/ + +NMConfig * +nm_config_get (void) +{ + g_assert (singleton); + return singleton; +} + +static int +sort_asciibetically (gconstpointer a, gconstpointer b) +{ + const char *s1 = *(const char **)a; + const char *s2 = *(const char **)b; + + return strcmp (s1, s2); +} + +/* call this function only once! */ +NMConfig * +nm_config_new (GError **error) +{ + NMConfigPrivate *priv = NULL; + GFile *dir; + GFileEnumerator *direnum; + GFileInfo *info; + GPtrArray *confs; + const char *name; + int i; + GString *config_description; + + g_assert (!singleton); + singleton = NM_CONFIG (g_object_new (NM_TYPE_CONFIG, NULL)); + priv = NM_CONFIG_GET_PRIVATE (singleton); + + /* First read the base config file */ + if (!find_base_config (singleton, error)) { + g_object_unref (singleton); + singleton = NULL; + return NULL; + } + + /* Now read the overrides in the config dir */ + if (cli_config_dir) + priv->config_dir = g_strdup (cli_config_dir); + else + priv->config_dir = g_strdup (NM_DEFAULT_SYSTEM_CONF_DIR); + + confs = g_ptr_array_new_with_free_func (g_free); + config_description = g_string_new (priv->nm_conf_path); + dir = g_file_new_for_path (priv->config_dir); + direnum = g_file_enumerate_children (dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL); + if (direnum) { + while ((info = g_file_enumerator_next_file (direnum, NULL, NULL))) { + name = g_file_info_get_name (info); + if (g_str_has_suffix (name, ".conf")) { + g_ptr_array_add (confs, g_build_filename (priv->config_dir, name, NULL)); + if (confs->len == 1) + g_string_append (config_description, " and conf.d: "); + else + g_string_append (config_description, ", "); + g_string_append (config_description, name); + } + g_object_unref (info); + } + g_object_unref (direnum); + } + g_object_unref (dir); + + g_ptr_array_sort (confs, sort_asciibetically); + priv->config_description = g_string_free (config_description, FALSE); + for (i = 0; i < confs->len; i++) { + if (!read_config (singleton, confs->pdata[i], error)) { + g_object_unref (singleton); + singleton = NULL; + break; + } + } + g_ptr_array_unref (confs); + if (!singleton) + return FALSE; + + /* Handle no-auto-default key and state file */ + priv->no_auto_default = g_key_file_get_string_list (priv->keyfile, "main", "no-auto-default", NULL, NULL); + if (cli_no_auto_default_file) + priv->no_auto_default_file = g_strdup (cli_no_auto_default_file); + else + priv->no_auto_default_file = g_strdup (NM_NO_AUTO_DEFAULT_STATE_FILE); + merge_no_auto_default_state (singleton); + + /* Now let command-line options override the config files, and fill in priv. */ + if (cli_plugins && cli_plugins[0]) + g_key_file_set_value (priv->keyfile, "main", "plugins", cli_plugins); + priv->plugins = g_key_file_get_string_list (priv->keyfile, "main", "plugins", NULL, NULL); + if (!priv->plugins && STRLEN (CONFIG_PLUGINS_DEFAULT) > 0) + priv->plugins = g_strsplit (CONFIG_PLUGINS_DEFAULT, ",", -1); + + priv->monitor_connection_files = _get_bool_value (priv->keyfile, "main", "monitor-connection-files", FALSE); + + priv->auth_polkit = _get_bool_value (priv->keyfile, "main", "auth-polkit", NM_CONFIG_DEFAULT_AUTH_POLKIT); + + priv->dhcp_client = g_key_file_get_value (priv->keyfile, "main", "dhcp", NULL); + priv->dns_mode = g_key_file_get_value (priv->keyfile, "main", "dns", NULL); + + priv->log_level = g_key_file_get_value (priv->keyfile, "logging", "level", NULL); + priv->log_domains = g_key_file_get_value (priv->keyfile, "logging", "domains", NULL); + + priv->debug = g_key_file_get_value (priv->keyfile, "main", "debug", NULL); + + if (cli_connectivity_uri && cli_connectivity_uri[0]) + g_key_file_set_value (priv->keyfile, "connectivity", "uri", cli_connectivity_uri); + priv->connectivity_uri = g_key_file_get_value (priv->keyfile, "connectivity", "uri", NULL); + + if (cli_connectivity_interval >= 0) + g_key_file_set_integer (priv->keyfile, "connectivity", "interval", cli_connectivity_interval); + priv->connectivity_interval = g_key_file_get_integer (priv->keyfile, "connectivity", "interval", NULL); + + if (cli_connectivity_response && cli_connectivity_response[0]) + g_key_file_set_value (priv->keyfile, "connectivity", "response", cli_connectivity_response); + priv->connectivity_response = g_key_file_get_value (priv->keyfile, "connectivity", "response", NULL); + + priv->ignore_carrier = g_key_file_get_string_list (priv->keyfile, "main", "ignore-carrier", NULL, NULL); + + priv->configure_and_quit = _get_bool_value (priv->keyfile, "main", "configure-and-quit", FALSE); + + return singleton; +} + +static void +nm_config_init (NMConfig *config) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (config); + + priv->auth_polkit = NM_CONFIG_DEFAULT_AUTH_POLKIT; + + priv->keyfile = g_key_file_new (); + g_key_file_set_list_separator (priv->keyfile, ','); + + priv->connectivity_interval = -1; +} + +static void +finalize (GObject *gobject) +{ + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE (gobject); + + g_free (priv->nm_conf_path); + g_free (priv->config_dir); + g_free (priv->config_description); + g_free (priv->no_auto_default_file); + g_clear_pointer (&priv->keyfile, g_key_file_unref); + g_strfreev (priv->plugins); + g_free (priv->dhcp_client); + g_free (priv->dns_mode); + g_free (priv->log_level); + g_free (priv->log_domains); + g_free (priv->debug); + g_free (priv->connectivity_uri); + g_free (priv->connectivity_response); + g_strfreev (priv->no_auto_default); + g_strfreev (priv->ignore_carrier); + + singleton = NULL; + + g_clear_pointer (&cli_config_path, g_free); + g_clear_pointer (&cli_config_dir, g_free); + g_clear_pointer (&cli_no_auto_default_file, g_free); + g_clear_pointer (&cli_plugins, g_free); + g_clear_pointer (&cli_connectivity_uri, g_free); + g_clear_pointer (&cli_connectivity_response, g_free); + + G_OBJECT_CLASS (nm_config_parent_class)->finalize (gobject); +} + + +static void +nm_config_class_init (NMConfigClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMConfigPrivate)); + object_class->finalize = finalize; +} + diff --git a/src/nm-config.h b/src/nm-config.h new file mode 100644 index 00000000..56f75fb5 --- /dev/null +++ b/src/nm-config.h @@ -0,0 +1,80 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2013 Thomas Bechtold + */ + +#ifndef __NETWORKMANAGER_CONFIG_H__ +#define __NETWORKMANAGER_CONFIG_H__ + +#include +#include + +#include "nm-types.h" + +G_BEGIN_DECLS + +#define NM_TYPE_CONFIG (nm_config_get_type ()) +#define NM_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONFIG, NMConfig)) +#define NM_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONFIG, NMConfigClass)) +#define NM_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONFIG)) +#define NM_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CONFIG)) +#define NM_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONFIG, NMConfigClass)) + +typedef struct { + GObject parent; +} NMConfig; + +typedef struct { + GObjectClass parent; +} NMConfigClass; + +GType nm_config_get_type (void); + +NMConfig *nm_config_get (void); + +const char *nm_config_get_path (NMConfig *config); +const char *nm_config_get_description (NMConfig *config); +const char **nm_config_get_plugins (NMConfig *config); +gboolean nm_config_get_monitor_connection_files (NMConfig *config); +gboolean nm_config_get_auth_polkit (NMConfig *config); +const char *nm_config_get_dhcp_client (NMConfig *config); +const char *nm_config_get_dns_mode (NMConfig *config); +const char *nm_config_get_log_level (NMConfig *config); +const char *nm_config_get_log_domains (NMConfig *config); +const char *nm_config_get_debug (NMConfig *config); +const char *nm_config_get_connectivity_uri (NMConfig *config); +guint nm_config_get_connectivity_interval (NMConfig *config); +const char *nm_config_get_connectivity_response (NMConfig *config); +gboolean nm_config_get_configure_and_quit (NMConfig *config); + +gboolean nm_config_get_ethernet_can_auto_default (NMConfig *config, NMDevice *device); +void nm_config_set_ethernet_no_auto_default (NMConfig *config, NMDevice *device); + +gboolean nm_config_get_ignore_carrier (NMConfig *config, NMDevice *device); + +char *nm_config_get_value (NMConfig *config, const char *group, const char *key, GError **error); + +/* for main.c only */ +GOptionEntry *nm_config_get_options (void); +NMConfig *nm_config_new (GError **error); + +G_END_DECLS + +#endif /* __NETWORKMANAGER_CONFIG_H__ */ + diff --git a/src/nm-connection-provider.c b/src/nm-connection-provider.c index f6ee7454..51caf400 100644 --- a/src/nm-connection-provider.c +++ b/src/nm-connection-provider.c @@ -13,6 +13,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ +#include "config.h" + #include "nm-connection-provider.h" #include "nm-utils.h" diff --git a/src/nm-connection-provider.h b/src/nm-connection-provider.h index 5093d055..8d5f7a69 100644 --- a/src/nm-connection-provider.h +++ b/src/nm-connection-provider.h @@ -13,19 +13,19 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#ifndef NM_CONNECTION_PROVIDER_H -#define NM_CONNECTION_PROVIDER_H +#ifndef __NETWORKMANAGER_CONNECTION_PROVIDER_H__ +#define __NETWORKMANAGER_CONNECTION_PROVIDER_H__ #include #include +#include "nm-types.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, NMConnectionProvider)) -typedef struct _NMConnectionProvider NMConnectionProvider; - #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" @@ -133,4 +133,4 @@ NMConnection *nm_connection_provider_add_connection (NMConnectionProvider *self, NMConnection *nm_connection_provider_get_connection_by_uuid (NMConnectionProvider *self, const char *uuid); -#endif /* NM_CONNECTION_PROVIDER_H */ +#endif /* __NETWORKMANAGER_CONNECTION_PROVIDER_H__ */ diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index 5c6a43f6..8a324a5c 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -19,7 +19,7 @@ * Copyright (C) 2011 Dan Williams */ -#include +#include "config.h" #include #if WITH_CONCHECK @@ -382,34 +382,30 @@ nm_connectivity_class_init (NMConnectivityClass *klass) /* properties */ g_object_class_install_property (object_class, PROP_URI, - g_param_spec_string (NM_CONNECTIVITY_URI, - "URI", - "Connectivity check URI", + g_param_spec_string (NM_CONNECTIVITY_URI, "", "", NULL, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INTERVAL, - g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, - "Interval", - "Connectivity check interval in seconds", + g_param_spec_uint (NM_CONNECTIVITY_INTERVAL, "", "", 0, G_MAXUINT, 300, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_RESPONSE, - g_param_spec_string (NM_CONNECTIVITY_RESPONSE, - "Response", - "Expected connectivity check reponse", + g_param_spec_string (NM_CONNECTIVITY_RESPONSE, "", "", DEFAULT_RESPONSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_CONNECTIVITY_STATE, - "State", - "Connectivity state", + g_param_spec_uint (NM_CONNECTIVITY_STATE, "", "", NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h index 04d0f2a3..771abdc2 100644 --- a/src/nm-connectivity.h +++ b/src/nm-connectivity.h @@ -18,14 +18,15 @@ * Copyright (C) 2011 Thomas Bechtold */ -#ifndef NM_CONNECTIVITY_H -#define NM_CONNECTIVITY_H +#ifndef __NETWORKMANAGER_CONNECTIVITY_H__ +#define __NETWORKMANAGER_CONNECTIVITY_H__ #include #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" +#include "nm-types.h" #define NM_TYPE_CONNECTIVITY (nm_connectivity_get_type ()) #define NM_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTIVITY, NMConnectivity)) @@ -40,9 +41,9 @@ #define NM_CONNECTIVITY_RESPONSE "response" #define NM_CONNECTIVITY_STATE "state" -typedef struct { +struct _NMConnectivity { GObject parent; -} NMConnectivity; +}; typedef struct { GObjectClass parent; @@ -64,4 +65,4 @@ NMConnectivityState nm_connectivity_check_finish (NMConnectivity *self, GAsyncResult *result, GError **error); -#endif /* NM_CONNECTIVITY_H */ +#endif /* __NETWORKMANAGER_CONNECTIVITY_H__ */ diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index f9269b61..1cceb9b5 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -20,12 +20,13 @@ */ #include "config.h" + #include #include #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-glib-compat.h" #include "nm-properties-changed-signal.h" @@ -96,7 +97,7 @@ nm_dbus_manager_get (void) /**************************************************************/ struct _PrivateServer { - char *tag; + const char *tag; GQuark detail; char *address; DBusServer *server; @@ -110,11 +111,12 @@ private_server_message_filter (DBusConnection *conn, void *data) { PrivateServer *s = data; + int fd; /* Clean up after the connection */ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) { - nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket.", - s->tag, conn); + nm_log_dbg (LOGD_CORE, "(%s) closed connection %p on private socket (fd %d).", + s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1); /* Emit this for the manager */ g_signal_emit (s->manager, @@ -145,6 +147,7 @@ private_server_new_connection (DBusServer *server, PrivateServer *s = user_data; static guint32 counter = 0; char *sender; + int fd; if (!dbus_connection_add_filter (conn, private_server_message_filter, s, NULL)) { dbus_connection_close (conn); @@ -157,7 +160,8 @@ private_server_new_connection (DBusServer *server, sender = g_strdup_printf ("x:y:%d", counter++); g_hash_table_insert (s->connections, dbus_connection_ref (conn), sender); - nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket.", s->tag, conn); + nm_log_dbg (LOGD_CORE, "(%s) accepted connection %p on private socket (fd %d).", + s->tag, conn, dbus_connection_get_unix_fd (conn, &fd) ? fd : -1); /* Emit this for the manager */ g_signal_emit (s->manager, @@ -208,8 +212,8 @@ private_server_new (const char *path, (GDestroyNotify) private_server_dbus_connection_destroy, g_free); s->manager = manager; - s->tag = g_strdup (tag); - s->detail = g_quark_from_string (s->tag); + s->detail = g_quark_from_string (tag); + s->tag = g_quark_to_string (s->detail); return s; } @@ -221,7 +225,6 @@ private_server_free (gpointer ptr) unlink (s->address); g_free (s->address); - g_free (s->tag); g_hash_table_destroy (s->connections); dbus_server_unref (s->server); memset (s, 0, sizeof (*s)); @@ -448,8 +451,8 @@ private_connection_new (NMDBusManager *self, DBusGConnection *connection) g_hash_table_iter_init (&iter, priv->exported); while (g_hash_table_iter_next (&iter, (gpointer) &object, (gpointer) &path)) { dbus_g_connection_register_g_object (connection, path, object); - nm_log_dbg (LOGD_CORE, "(%s) registered %p (%s) at '%s' on private socket.", - PRIV_SOCK_TAG, object, G_OBJECT_TYPE_NAME (object), path); + nm_log_trace (LOGD_CORE, "(%s) registered %p (%s) at '%s' on private socket.", + PRIV_SOCK_TAG, object, G_OBJECT_TYPE_NAME (object), path); } } diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h index 7895a203..cc7f3210 100644 --- a/src/nm-dbus-manager.h +++ b/src/nm-dbus-manager.h @@ -27,6 +27,8 @@ #include #include +#include "nm-types.h" + G_BEGIN_DECLS typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection, @@ -45,9 +47,9 @@ typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection, #define NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "private-connection-new" #define NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "private-connection-disconnected" -typedef struct { +struct _NMDBusManager { GObject parent; -} NMDBusManager; +}; typedef struct { GObjectClass parent; diff --git a/src/nm-dcb.c b/src/nm-dcb.c index 3bdbf7d5..6faec5c5 100644 --- a/src/nm-dcb.c +++ b/src/nm-dcb.c @@ -18,7 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -29,16 +30,6 @@ #include "nm-posix-signals.h" #include "nm-logging.h" -GQuark -nm_dcb_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm-dcb-error"); - return ret; -} - static const char *helper_names[] = { "dcbtool", "fcoeadm" }; gboolean @@ -63,7 +54,7 @@ do_helper (const char *iface, split = g_strsplit_set (cmdline, " ", 0); if (!split) { - g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_INTERNAL, + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "failure parsing %s command line", helper_names[which]); goto out; } @@ -296,47 +287,20 @@ _fcoe_cleanup (const char *iface, return do_helper (NULL, FCOEADM, run_func, user_data, error, "-d %s", iface); } - -static const char *dcbpaths[] = { - "/sbin/dcbtool", - "/usr/sbin/dcbtool", - "/usr/local/sbin/dcbtool", - NULL -}; -static const char *fcoepaths[] = { - "/sbin/fcoeadm", - "/usr/sbin/fcoeadm", - "/usr/local/sbin/fcoeadm", - NULL -}; - - static gboolean run_helper (char **argv, guint which, gpointer user_data, GError **error) { - static const char *helper_path[2] = { NULL, NULL }; + const char *helper_path; int exit_status = 0; gboolean success; char *errmsg = NULL, *outmsg = NULL; - const char **iter; char *cmdline; - if (G_UNLIKELY (helper_path[which] == NULL)) { - iter = (which == DCBTOOL) ? dcbpaths : fcoepaths; - while (*iter) { - if (g_file_test (*iter, G_FILE_TEST_EXISTS)) - helper_path[which] = *iter; - iter++; - } - if (!helper_path[which]) { - g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_HELPER_NOT_FOUND, - "%s not found", - which == DCBTOOL ? "dcbtool" : "fcoadm"); - return FALSE; - } - } + helper_path = nm_utils_find_helper ((which == DCBTOOL) ? "dcbtool" : "fcoeadm", NULL, error); + if (!helper_path) + return FALSE; - argv[0] = (char *) helper_path[which]; + argv[0] = (char *) helper_path; cmdline = g_strjoinv (" ", argv); nm_log_dbg (LOGD_DCB, "%s", cmdline); @@ -354,14 +318,14 @@ run_helper (char **argv, guint which, gpointer user_data, GError **error) if (ignore_error == FALSE) { nm_log_warn (LOGD_DCB, "'%s' failed: '%s'", cmdline, (errmsg && strlen (errmsg)) ? errmsg : outmsg); - g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_HELPER_FAILED, + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "Failed to run '%s'", cmdline); success = FALSE; } } + g_free (outmsg); g_free (errmsg); - g_free (cmdline); return success; } diff --git a/src/nm-dcb.h b/src/nm-dcb.h index bfe5cedf..e409dd48 100644 --- a/src/nm-dcb.h +++ b/src/nm-dcb.h @@ -18,36 +18,12 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_DCB_H -#define NM_DCB_H +#ifndef __NETWORKMANAGER_DCB_H__ +#define __NETWORKMANAGER_DCB_H__ #include #include "nm-setting-dcb.h" -/** - * NMDcbError: - * @NM_DCB_ERROR_UNKNOWN: unknown or unclassified error - * @NM_DCB_ERROR_INTERNAL: a internal programmer error - * @NM_DCB_ERROR_BAD_CONFIG: configuration was invalid - * @NM_DCB_ERROR_HELPER_NOT_FOUND: the required helper program was not found - * @NM_DCB_ERROR_HELPER_FAILED: the helper program failed - * - * NOTE: these errors are internal-use only and should never be used with D-Bus. - **/ -typedef enum { - NM_DCB_ERROR_UNKNOWN = 0, - NM_DCB_ERROR_INTERNAL, - NM_DCB_ERROR_BAD_CONFIG, - NM_DCB_ERROR_HELPER_NOT_FOUND, - NM_DCB_ERROR_HELPER_FAILED, -} NMDcbError; - -#define NM_DCB_ERROR (nm_dcb_error_quark ()) -GQuark nm_dcb_error_quark (void); -#define NM_TYPE_DCB_ERROR (nm_dcb_error_get_type ()) -GType nm_dcb_error_get_type (void); - - gboolean nm_dcb_enable (const char *iface, gboolean enable, GError **error); gboolean nm_dcb_setup (const char *iface, NMSettingDcb *s_dcb, GError **error); gboolean nm_dcb_cleanup (const char *iface, GError **error); @@ -97,4 +73,4 @@ gboolean _fcoe_cleanup (const char *iface, gpointer user_data, GError **error); -#endif /* NM_DCB_H */ +#endif /* __NETWORKMANAGER_DCB_H__ */ diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c new file mode 100644 index 00000000..5cc1bcd2 --- /dev/null +++ b/src/nm-default-route-manager.c @@ -0,0 +1,1365 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + + +#include "config.h" + +#include "nm-default-route-manager.h" + +#include "string.h" + +#include "nm-logging.h" +#include "nm-device.h" +#include "nm-vpn-connection.h" +#include "nm-platform.h" +#include "nm-manager.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" +#include "nm-activation-request.h" + +typedef struct { + GPtrArray *entries_ip4; + GPtrArray *entries_ip6; + struct { + guint guard; + guint backoff_wait_time_ms; + guint idle_handle; + gboolean has_v4_changes; + gboolean has_v6_changes; + } resync; +} NMDefaultRouteManagerPrivate; + +#define NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerPrivate)) + +G_DEFINE_TYPE (NMDefaultRouteManager, nm_default_route_manager, G_TYPE_OBJECT) + +static NMDefaultRouteManager *_instance; + +#define _LOG(level, addr_family, ...) \ + G_STMT_START { \ + int __addr_family = (addr_family); \ + guint64 __domain = __addr_family == AF_INET ? LOGD_IP4 : LOGD_IP6; \ + \ + if (nm_logging_enabled ((level), (__domain))) { \ + char __ch = __addr_family == AF_INET ? '4' : (__addr_family == AF_INET6 ? '6' : '-'); \ + char __prefix[30] = "default-route"; \ + \ + if ((self) != _instance) \ + g_snprintf (__prefix, sizeof (__prefix), "default-route%c[%p]", __ch, (self)); \ + else \ + __prefix[STRLEN ("default-route")] = __ch; \ + nm_log ((level), (__domain), \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __prefix _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } G_STMT_END + +#define _LOGD(addr_family, ...) _LOG (LOGL_DEBUG, addr_family, __VA_ARGS__) +#define _LOGI(addr_family, ...) _LOG (LOGL_INFO , addr_family, __VA_ARGS__) +#define _LOGW(addr_family, ...) _LOG (LOGL_WARN , addr_family, __VA_ARGS__) +#define _LOGE(addr_family, ...) _LOG (LOGL_ERR , addr_family, __VA_ARGS__) + +#define LOG_ENTRY_FMT "entry[%u/%s:%p:%s:%c%c]" +#define LOG_ENTRY_ARGS(entry_idx, entry) \ + (entry_idx), \ + NM_IS_DEVICE ((entry)->source.pointer) ? "dev" : "vpn", \ + (entry)->source.pointer, \ + NM_IS_DEVICE ((entry)->source.pointer) ? nm_device_get_iface ((entry)->source.device) : nm_vpn_connection_get_connection_id ((entry)->source.vpn), \ + ((entry)->never_default ? 'N' : 'n'), \ + ((entry)->synced ? 'S' : 's') + +/***********************************************************************************/ + +static void _resync_idle_cancel (NMDefaultRouteManager *self); + +/***********************************************************************************/ + +typedef struct { + union { + void *pointer; + GObject *object; + NMDevice *device; + NMVpnConnection *vpn; + } source; + NMPlatformIPXRoute route; + + /* Whether the route is synced to platform and has a default route. + * + * ( synced && !never_default): the interface gets a default route that + * is enforced and managed by NMDefaultRouteManager. + * + * (!synced && !never_default): the interface has this route, but it is assumed. + * Assumed interfaces are those that have no tracked entry or that only have + * (!synced && !never_default) entries. NMDefaultRouteManager will not touch + * default routes on these interfaces. + * This combination makes only sense for device sources. + * They are tracked so that assumed devices can also be the best device. + * + * ( synced && never_default): entries of this kind are a placeholder + * to indicate that the ifindex is managed but has no default-route. + * Missing entries also indicate that a certain ifindex has no default-route. + * The difference is that missing entries are considered assumed while on + * (synced && never_default) entires the absence of the default route + * is enforced. NMDefaultRouteManager will actively remove any default + * route on such ifindexes. + * Also, for VPN sources in addition we track them so that a never-default + * VPN connection can be choosen by get_best_config() to receive the DNS configuration. + * + * (!synced && never_default): this combination makes no sense. + */ + gboolean synced; + gboolean never_default; + + guint32 effective_metric; +} Entry; + +typedef struct { + int addr_family; + GPtrArray *(*get_entries) (NMDefaultRouteManagerPrivate *priv); + const char *(*platform_route_to_string) (const NMPlatformIPRoute *route); + GArray *(*platform_route_get_all) (int ifindex, NMPlatformGetRouteMode mode); + gboolean (*platform_route_delete_default) (int ifindex, guint32 metric); + guint32 (*route_metric_normalize) (guint32 metric); +} VTableIP; + +static const VTableIP vtable_ip4, vtable_ip6; + +#define VTABLE_IS_IP4 (vtable->addr_family == AF_INET) + +static NMPlatformIPRoute * +_vt_route_index (const VTableIP *vtable, GArray *routes, guint index) +{ + if (VTABLE_IS_IP4) + return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP4Route, index); + else + return (NMPlatformIPRoute *) &g_array_index (routes, NMPlatformIP6Route, index); +} + +static gboolean +_vt_routes_has_entry (const VTableIP *vtable, GArray *routes, const Entry *entry) +{ + guint i; + NMPlatformIPXRoute route = entry->route; + + route.rx.metric = entry->effective_metric; + + if (VTABLE_IS_IP4) { + for (i = 0; i < routes->len; i++) { + NMPlatformIP4Route *r = &g_array_index (routes, NMPlatformIP4Route, i); + + route.rx.source = r->source; + if (nm_platform_ip4_route_cmp (r, &route.r4) == 0) + return TRUE; + } + } else { + for (i = 0; i < routes->len; i++) { + NMPlatformIP6Route *r = &g_array_index (routes, NMPlatformIP6Route, i); + + route.rx.source = r->source; + if (nm_platform_ip6_route_cmp (r, &route.r6) == 0) + return TRUE; + } + } + return FALSE; +} + +static void +_entry_free (Entry *entry) +{ + if (entry) { + g_object_unref (entry->source.object); + g_slice_free (Entry, entry); + } +} + +static Entry * +_entry_find_by_source (GPtrArray *entries, gpointer source, guint *out_idx) +{ + guint i; + + for (i = 0; i < entries->len; i++) { + Entry *e = g_ptr_array_index (entries, i); + + if (e->source.pointer == source) { + if (out_idx) + *out_idx = i; + return e; + } + } + + if (out_idx) + *out_idx = G_MAXUINT; + return NULL; +} + +static gboolean +_platform_route_sync_add (const VTableIP *vtable, NMDefaultRouteManager *self, guint32 metric) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + GPtrArray *entries = vtable->get_entries (priv); + guint i; + Entry *entry_unsynced = NULL; + Entry *entry = NULL; + gboolean success; + + /* Find the entries for the given metric. + * The effective metric for synced entries is choosen in a way that it + * is unique (except for G_MAXUINT32, where a clash is not solvable). */ + for (i = 0; i < entries->len; i++) { + Entry *e = g_ptr_array_index (entries, i); + + if (e->never_default) + continue; + + if (e->effective_metric != metric) + continue; + + if (e->synced) { + g_assert (!entry || metric == G_MAXUINT32); + if (!entry) + entry = e; + } else + entry_unsynced = e; + } + + /* We don't expect to have an unsynced *and* a synced entry for the same metric. + * Unless, (a) their metric is G_MAXUINT32, in which case we could not find an unused effective metric, + * or (b) if we have an unsynced and a synced entry for the same ifindex. + * The latter case happens for example when activating an openvpn connection (synced) and + * assuming the corresponding tun0 interface (unsynced). */ + g_assert (!entry || !entry_unsynced || (entry->route.rx.ifindex == entry_unsynced->route.rx.ifindex) || metric == G_MAXUINT32); + + /* we only add the route, if we have an (to be synced) entry for it. */ + if (!entry) + return FALSE; + + if (VTABLE_IS_IP4) { + success = nm_platform_ip4_route_add (entry->route.rx.ifindex, + entry->route.rx.source, + 0, + 0, + entry->route.r4.gateway, + 0, + entry->effective_metric, + entry->route.rx.mss); + } else { + success = nm_platform_ip6_route_add (entry->route.rx.ifindex, + entry->route.rx.source, + in6addr_any, + 0, + entry->route.r6.gateway, + entry->effective_metric, + entry->route.rx.mss); + } + if (!success) { + _LOGW (vtable->addr_family, "failed to add default route %s with effective metric %u", + vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric); + } + return TRUE; +} + +static gboolean +_platform_route_sync_flush (const VTableIP *vtable, NMDefaultRouteManager *self, int ifindex_to_flush) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + GPtrArray *entries = vtable->get_entries (priv); + GArray *routes; + guint i, j; + gboolean changed = FALSE; + + /* prune all other default routes from this device. */ + routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + + for (i = 0; i < routes->len; i++) { + const NMPlatformIPRoute *route; + gboolean has_ifindex_synced = FALSE; + Entry *entry = NULL; + + route = _vt_route_index (vtable, routes, i); + + /* look at all entires and see if the route for this ifindex pair is + * a known entry. */ + for (j = 0; j < entries->len; j++) { + Entry *e = g_ptr_array_index (entries, j); + + if ( e->route.rx.ifindex == route->ifindex + && e->synced) { + has_ifindex_synced = TRUE; + if ( !e->never_default + && e->effective_metric == route->metric) + entry = e; + } + } + + /* we only delete the route if we don't have a matching entry, + * and there is at least one entry that references this ifindex + * (indicating that the ifindex is managed by us -- not assumed). + * + * Otherwise, don't delete the route because it's configured + * externally (and will be assumed -- or already is assumed). + */ + if ( !entry + && (has_ifindex_synced || ifindex_to_flush == route->ifindex)) { + vtable->platform_route_delete_default (route->ifindex, route->metric); + changed = TRUE; + } + } + g_array_free (routes, TRUE); + return changed; +} + +static int +_sort_entries_cmp (gconstpointer a, gconstpointer b, gpointer user_data) +{ + guint32 m_a, m_b; + const Entry *e_a = *((const Entry **) a); + const Entry *e_b = *((const Entry **) b); + + /* when comparing routes, we consider the (original) metric. */ + m_a = e_a->route.rx.metric; + m_b = e_b->route.rx.metric; + + /* we normalize route.metric already in _ipx_update_default_route(). + * so we can just compare the metrics numerically */ + + if (m_a != m_b) + return (m_a < m_b) ? -1 : 1; + + /* If the metrics are equal, we prefer the one that is !never_default */ + if (!!e_a->never_default != !!e_b->never_default) + return e_a->never_default ? 1 : -1; + + /* If the metrics are equal, we prefer the one that is assumed (!synced). + * Entries that we sync, can be modified so that only the best + * entry has a (deterministically) lowest metric. + * With assumed devices we cannot increase/change the metric. + * For example: two devices, both metric 0. One is assumed the other is + * synced. + * If we would choose the synced entry as best, we cannot + * increase the metric of the assumed one and we would have non-determinism. + * If we instead prefer the assumed device, we can increase the metric + * of the synced device and the assumed device is (deterministically) + * prefered. + * If both devices are assumed, we also have non-determinism, but also + * we don't reorder either. + */ + if (!!e_a->synced != !!e_b->synced) + return e_a->synced ? 1 : -1; + + /* otherwise, do not reorder */ + return 0; +} + +static GHashTable * +_get_assumed_interface_metrics (const VTableIP *vtable, NMDefaultRouteManager *self, GArray *routes) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + GPtrArray *entries; + guint i, j; + GHashTable *result; + + /* create a list of all metrics that are currently assigned on an interface + * that is *not* already covered by one of our synced entries. + * IOW, returns the metrics that are in use by assumed interfaces + * that we want to preserve. */ + + entries = vtable->get_entries (priv); + + result = g_hash_table_new (NULL, NULL); + + for (i = 0; i < routes->len; i++) { + gboolean ifindex_has_synced_entry = FALSE; + const NMPlatformIPRoute *route; + + route = _vt_route_index (vtable, routes, i); + + for (j = 0; j < entries->len; j++) { + Entry *e = g_ptr_array_index (entries, j); + + if ( e->synced + && e->route.rx.ifindex == route->ifindex) { + ifindex_has_synced_entry = TRUE; + break; + } + } + + if (!ifindex_has_synced_entry) + g_hash_table_add (result, GUINT_TO_POINTER (vtable->route_metric_normalize (route->metric))); + } + + return result; +} + +static int +_sort_metrics_ascending_fcn (gconstpointer a, gconstpointer b) +{ + guint32 m_a = *((guint32 *) a); + guint32 m_b = *((guint32 *) b); + + if (m_a < m_b) + return -1; + return m_a == m_b ? 0 : 1; +} + +static gboolean +_resync_all (const VTableIP *vtable, NMDefaultRouteManager *self, const Entry *changed_entry, const Entry *old_entry, gboolean external_change) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + Entry *entry; + guint i, j; + gint64 last_metric = -1; + guint32 expected_metric; + GPtrArray *entries; + GArray *changed_metrics = g_array_new (FALSE, FALSE, sizeof (guint32)); + GHashTable *assumed_metrics; + GArray *routes; + gboolean changed = FALSE; + int ifindex_to_flush = 0; + + g_assert (priv->resync.guard == 0); + priv->resync.guard++; + + if (!external_change) { + if (VTABLE_IS_IP4) + priv->resync.has_v4_changes = FALSE; + else + priv->resync.has_v6_changes = FALSE; + if (!priv->resync.has_v4_changes && !priv->resync.has_v6_changes) + _resync_idle_cancel (self); + } + + entries = vtable->get_entries (priv); + + routes = vtable->platform_route_get_all (0, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT); + + assumed_metrics = _get_assumed_interface_metrics (vtable, self, routes); + + if (old_entry && old_entry->synced && !old_entry->never_default) { + /* The old version obviously changed. */ + g_array_append_val (changed_metrics, old_entry->effective_metric); + } + + /* first iterate over all entries and adjust the effective metrics. */ + for (i = 0; i < entries->len; i++) { + entry = g_ptr_array_index (entries, i); + + g_assert (entry != old_entry); + + if (entry->never_default) + continue; + + if (!entry->synced) { + gboolean has_synced_entry = FALSE; + + /* A non synced entry is completely ignored, if we have + * a synced entry for the same if index. + * Otherwise the metric of the entry is still remembered as + * last_metric to avoid reusing it. */ + for (j = 0; j < entries->len; j++) { + const Entry *e = g_ptr_array_index (entries, j); + + if ( e->synced + && e->route.rx.ifindex == entry->route.rx.ifindex) { + has_synced_entry = TRUE; + break; + } + } + if (!has_synced_entry) + last_metric = MAX (last_metric, (gint64) entry->effective_metric); + continue; + } + + expected_metric = entry->route.rx.metric; + if ((gint64) expected_metric <= last_metric) + expected_metric = last_metric == G_MAXUINT32 ? G_MAXUINT32 : last_metric + 1; + + while ( expected_metric < G_MAXUINT32 + && g_hash_table_contains (assumed_metrics, GUINT_TO_POINTER (expected_metric))) { + gboolean has_metric_for_ifindex = FALSE; + + /* Check if there are assumed devices that have default routes with this metric. + * If there are any, we have to pick another effective_metric. */ + + /* However, if there is a matching route (ifindex+metric) for our current entry, we are done. */ + for (j = 0; j < routes->len; j++) { + const NMPlatformIPRoute *r = _vt_route_index (vtable, routes, i); + + if ( r->metric == expected_metric + && r->ifindex == entry->route.rx.ifindex) { + has_metric_for_ifindex = TRUE; + break; + } + } + if (has_metric_for_ifindex) + break; + expected_metric++; + } + + if (changed_entry == entry) { + /* for the changed entry, the previous metric was either old_entry->effective_metric, + * or none. Hence, we only have to remember what is going to change. */ + g_array_append_val (changed_metrics, expected_metric); + if (old_entry) { + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": update %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->platform_route_to_string (&entry->route.rx), (guint) old_entry->effective_metric, + (guint) expected_metric); + } else { + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": add %s (%u)", LOG_ENTRY_ARGS (i, entry), + vtable->platform_route_to_string (&entry->route.rx), (guint) expected_metric); + } + } else if (entry->effective_metric != expected_metric) { + g_array_append_val (changed_metrics, entry->effective_metric); + g_array_append_val (changed_metrics, expected_metric); + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": resync metric %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric, + (guint) expected_metric); + } else { + if (!_vt_routes_has_entry (vtable, routes, entry)) { + g_array_append_val (changed_metrics, entry->effective_metric); + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": readd route %s (%u -> %u)", LOG_ENTRY_ARGS (i, entry), + vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric, + (guint) entry->effective_metric); + } + } + + if (entry->effective_metric != expected_metric) { + entry->effective_metric = expected_metric; + changed = TRUE; + } + last_metric = expected_metric; + } + + g_array_free (routes, TRUE); + + g_array_sort (changed_metrics, _sort_metrics_ascending_fcn); + last_metric = -1; + for (j = 0; j < changed_metrics->len; j++) { + expected_metric = g_array_index (changed_metrics, guint32, j); + + if (last_metric == (gint64) expected_metric) { + /* skip duplicates. */ + continue; + } + changed |= _platform_route_sync_add (vtable, self, expected_metric); + last_metric = expected_metric; + } + + if ( old_entry + && !changed_entry + && old_entry->synced + && !old_entry->never_default) { + /* If we entriely remove an entry that was synced before, we must make + * sure to flush routes for this ifindex too. Otherwise they linger + * around as "assumed" routes */ + ifindex_to_flush = old_entry->route.rx.ifindex; + } + + changed |= _platform_route_sync_flush (vtable, self, ifindex_to_flush); + + g_array_free (changed_metrics, TRUE); + g_hash_table_unref (assumed_metrics); + + priv->resync.guard--; + return changed; +} + +static void +_entry_at_idx_update (const VTableIP *vtable, NMDefaultRouteManager *self, guint entry_idx, const Entry *old_entry) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + Entry *entry; + GPtrArray *entries; + + entries = vtable->get_entries (priv); + g_assert (entry_idx < entries->len); + + entry = g_ptr_array_index (entries, entry_idx); + + g_assert ( !old_entry + || (entry->source.pointer == old_entry->source.pointer && entry->route.rx.ifindex == old_entry->route.rx.ifindex)); + + if (!entry->synced && !entry->never_default) + entry->effective_metric = entry->route.rx.metric; + + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": %s %s", + LOG_ENTRY_ARGS (entry_idx, entry), + old_entry ? "update" : "add", + vtable->platform_route_to_string (&entry->route.rx)); + + g_ptr_array_sort_with_data (entries, _sort_entries_cmp, NULL); + + _resync_all (vtable, self, entry, old_entry, FALSE); +} + +static void +_entry_at_idx_remove (const VTableIP *vtable, NMDefaultRouteManager *self, guint entry_idx) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + Entry *entry; + GPtrArray *entries; + + entries = vtable->get_entries (priv); + + g_assert (entry_idx < entries->len); + + entry = g_ptr_array_index (entries, entry_idx); + + _LOGD (vtable->addr_family, LOG_ENTRY_FMT": remove %s (%u)", LOG_ENTRY_ARGS (entry_idx, entry), + vtable->platform_route_to_string (&entry->route.rx), (guint) entry->effective_metric); + + /* Remove the entry from the list (but don't free it yet) */ + g_ptr_array_index (entries, entry_idx) = NULL; + g_ptr_array_remove_index (entries, entry_idx); + + _resync_all (vtable, self, NULL, entry, FALSE); + + _entry_free (entry); +} + +/***********************************************************************************/ + +static void +_ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, gpointer source) +{ + NMDefaultRouteManagerPrivate *priv; + Entry *entry; + guint entry_idx; + const NMPlatformIPRoute *default_route = NULL; + NMPlatformIPXRoute rt; + int ip_ifindex; + GPtrArray *entries; + NMDevice *device = NULL; + NMVpnConnection *vpn = NULL; + gboolean never_default = FALSE; + gboolean synced = FALSE; + + g_return_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self)); + if (NM_IS_DEVICE (source)) + device = source; + else if (NM_IS_VPN_CONNECTION (source)) + vpn = source; + else + g_return_if_reached (); + + 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); + } + } + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + entries = vtable->get_entries (priv); + entry = _entry_find_by_source (entries, source, &entry_idx); + + if ( entry + && entry->route.rx.ifindex != ip_ifindex) { + /* Strange... the ifindex changed... Remove the device and start again. */ + _LOGD (vtable->addr_family, "ifindex of "LOG_ENTRY_FMT" changed: %d -> %d", + LOG_ENTRY_ARGS (entry_idx, entry), + entry->route.rx.ifindex, ip_ifindex); + + g_object_freeze_notify (G_OBJECT (self)); + _entry_at_idx_remove (vtable, self, entry_idx); + g_assert (!_entry_find_by_source (entries, source, NULL)); + _ipx_update_default_route (vtable, self, source); + g_object_thaw_notify (G_OBJECT (self)); + return; + } + + /* get the @default_route from the device. */ + if (ip_ifindex > 0) { + if (device) { + gboolean is_assumed; + + if (VTABLE_IS_IP4) + default_route = (const NMPlatformIPRoute *) nm_device_get_ip4_default_route (device, &is_assumed); + else + default_route = (const NMPlatformIPRoute *) nm_device_get_ip6_default_route (device, &is_assumed); + if (!default_route && !is_assumed) { + /* the device has no default route, but it is not assumed. That means, NMDefaultRouteManager + * enforces that the device has no default route. + * + * Hence we have to keep track of this entry, otherwise a missing entry tells us + * that the interface is assumed and NM would not remove the default routes on + * the device. */ + memset (&rt, 0, sizeof (rt)); + rt.rx.ifindex = ip_ifindex; + rt.rx.source = NM_IP_CONFIG_SOURCE_UNKNOWN; + rt.rx.metric = G_MAXUINT32; + default_route = &rt.rx; + + never_default = TRUE; + synced = TRUE; + } else + synced = default_route && !is_assumed; + } else { + NMConnection *connection = nm_active_connection_get_connection ((NMActiveConnection *) vpn); + + if ( connection + && nm_vpn_connection_get_vpn_state (vpn) == NM_VPN_CONNECTION_STATE_ACTIVATED) { + + memset (&rt, 0, sizeof (rt)); + if (VTABLE_IS_IP4) { + NMIP4Config *vpn_config; + + vpn_config = nm_vpn_connection_get_ip4_config (vpn); + 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.gateway = nm_vpn_connection_get_ip4_internal_gateway (vpn); + rt.r4.metric = nm_vpn_connection_get_ip4_route_metric (vpn); + rt.r4.mss = nm_ip4_config_get_mss (vpn_config); + default_route = &rt.rx; + } + } else { + NMIP6Config *vpn_config; + + vpn_config = nm_vpn_connection_get_ip6_config (vpn); + if (vpn_config) { + const struct in6_addr *int_gw = nm_vpn_connection_get_ip6_internal_gateway (vpn); + + 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.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); + default_route = &rt.rx; + } + } + } + synced = TRUE; + } + } + g_assert (!default_route || default_route->plen == 0); + + if (!entry && !default_route) + /* nothing to do */; + else if (!entry) { + /* add */ + entry = g_slice_new0 (Entry); + entry->source.object = g_object_ref (source); + + if (VTABLE_IS_IP4) + entry->route.r4 = *((const NMPlatformIP4Route *) default_route); + else + entry->route.r6 = *((const NMPlatformIP6Route *) default_route); + + /* only use normalized metrics */ + entry->route.rx.metric = vtable->route_metric_normalize (entry->route.rx.metric); + entry->route.rx.ifindex = ip_ifindex; + entry->never_default = never_default; + entry->effective_metric = entry->route.rx.metric; + entry->synced = synced; + + g_ptr_array_add (entries, entry); + _entry_at_idx_update (vtable, self, entries->len - 1, NULL); + } else if (default_route) { + /* update */ + Entry old_entry, new_entry; + + new_entry = *entry; + if (VTABLE_IS_IP4) + new_entry.route.r4 = *((const NMPlatformIP4Route *) default_route); + else + new_entry.route.r6 = *((const NMPlatformIP6Route *) default_route); + /* only use normalized metrics */ + new_entry.route.rx.metric = vtable->route_metric_normalize (new_entry.route.rx.metric); + new_entry.route.rx.ifindex = ip_ifindex; + new_entry.never_default = never_default; + new_entry.synced = synced; + + if (memcmp (entry, &new_entry, sizeof (new_entry)) == 0) + return; + + old_entry = *entry; + *entry = new_entry; + _entry_at_idx_update (vtable, self, entry_idx, &old_entry); + } else { + /* delete */ + _entry_at_idx_remove (vtable, self, entry_idx); + } +} + +void +nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *self, gpointer source) +{ + _ipx_update_default_route (&vtable_ip4, self, source); +} + +void +nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *self, gpointer source) +{ + _ipx_update_default_route (&vtable_ip6, self, source); +} + +/***********************************************************************************/ + +static gboolean +_ipx_connection_has_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, NMConnection *connection) +{ + const char *method; + NMSettingIPConfig *s_ip; + + g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + if (VTABLE_IS_IP4) + s_ip = nm_connection_get_setting_ip4_config (connection); + else + s_ip = nm_connection_get_setting_ip6_config (connection); + if (!s_ip || nm_setting_ip_config_get_never_default (s_ip)) + return FALSE; + + if (VTABLE_IS_IP4) { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + if ( !method + || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + return FALSE; + } else { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if ( !method + || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) + || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) + return FALSE; + } + + return TRUE; +} + +gboolean +nm_default_route_manager_ip4_connection_has_default_route (NMDefaultRouteManager *self, NMConnection *connection) +{ + return _ipx_connection_has_default_route (&vtable_ip4, self, connection); +} + +gboolean +nm_default_route_manager_ip6_connection_has_default_route (NMDefaultRouteManager *self, NMConnection *connection) +{ + return _ipx_connection_has_default_route (&vtable_ip6, self, connection); +} + +/***********************************************************************************/ + +static NMDevice * +_ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const GSList *devices) +{ + NMDefaultRouteManagerPrivate *priv; + GPtrArray *entries; + guint i; + + g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); + + if (!devices) + return NULL; + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + entries = vtable->get_entries (priv); + + for (i = 0; i < entries->len; i++) { + Entry *entry = g_ptr_array_index (entries, i); + + if (!NM_IS_DEVICE (entry->source.pointer)) + continue; + + if (entry->never_default) + continue; + + if (g_slist_find ((GSList *) devices, entry->source.device)) + return entry->source.pointer; + } + return NULL; +} + +/** _ipx_get_best_activating_device: + * @vtable: the virtual table + * @self: #NMDefaultRouteManager + * @devices: list of devices to be searched. Only devices from this list will be considered + * @fully_activated: if #TRUE, only search for devices that are fully activated. Otherwise, + * search if there is a best device going to be activated. In the latter case, this will + * return NULL if the best device is already activated. + * @preferred_device: if not-NULL, this device is preferred if there are more devices with + * the same priority. + **/ +static NMDevice * +_ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager *self, const GSList *devices, NMDevice *preferred_device) +{ + NMDefaultRouteManagerPrivate *priv; + const GSList *iter; + NMDevice *best_device = NULL; + guint32 best_prio = G_MAXUINT32; + NMDevice *best_activated_device; + + g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + best_activated_device = _ipx_get_best_device (vtable, self, devices); + + for (iter = devices; iter; iter = g_slist_next (iter)) { + NMDevice *device = NM_DEVICE (iter->data); + guint32 prio; + Entry *entry; + + entry = _entry_find_by_source (vtable->get_entries (priv), device, NULL); + + if (entry) { + /* of all the device that have an entry, we already know that best_activated_device + * is the best. entry cannot be better. */ + if (entry->source.device != best_activated_device) + continue; + prio = entry->effective_metric; + } else { + NMDeviceState state = nm_device_get_state (device); + + if ( state <= NM_DEVICE_STATE_DISCONNECTED + || state >= NM_DEVICE_STATE_DEACTIVATING) + continue; + + if (!_ipx_connection_has_default_route (vtable, self, nm_device_get_connection (device))) + continue; + + prio = nm_device_get_ip4_route_metric (device); + } + prio = vtable->route_metric_normalize (prio); + + if ( !best_device + || prio < best_prio + || (prio == best_prio && preferred_device == device)) { + best_device = device; + best_prio = prio; + } + } + + /* There's only a best activating device if the best device + * among all activating and already-activated devices is a + * still-activating one. + */ + if (best_device && nm_device_get_state (best_device) >= NM_DEVICE_STATE_SECONDARIES) + return NULL; + return best_device; +} + +NMDevice * +nm_default_route_manager_ip4_get_best_device (NMDefaultRouteManager *self, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device) +{ + if (fully_activated) + return _ipx_get_best_device (&vtable_ip4, self, devices); + else + return _ipx_get_best_activating_device (&vtable_ip4, self, devices, preferred_device); +} + +NMDevice * +nm_default_route_manager_ip6_get_best_device (NMDefaultRouteManager *self, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device) +{ + if (fully_activated) + return _ipx_get_best_device (&vtable_ip6, self, devices); + else + return _ipx_get_best_activating_device (&vtable_ip6, self, devices, preferred_device); +} + +/***********************************************************************************/ + +static gpointer +_ipx_get_best_config (const VTableIP *vtable, + NMDefaultRouteManager *self, + gboolean ignore_never_default, + const char **out_ip_iface, + NMActiveConnection **out_ac, + NMDevice **out_device, + NMVpnConnection **out_vpn) +{ + NMDefaultRouteManagerPrivate *priv; + GPtrArray *entries; + guint i; + gpointer config_result = NULL; + + g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); + + if (out_ip_iface) + *out_ip_iface = NULL; + if (out_ac) + *out_ac = NULL; + if (out_device) + *out_device = NULL; + if (out_vpn) + *out_vpn = NULL; + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), NULL); + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + entries = vtable->get_entries (priv); + + for (i = 0; i < entries->len; i++) { + Entry *entry = g_ptr_array_index (entries, i); + + if (!NM_IS_DEVICE (entry->source.pointer)) { + NMVpnConnection *vpn = NM_VPN_CONNECTION (entry->source.vpn); + + if (entry->never_default && !ignore_never_default) + continue; + + if (VTABLE_IS_IP4) + config_result = nm_vpn_connection_get_ip4_config (vpn); + else + config_result = nm_vpn_connection_get_ip6_config (vpn); + g_assert (config_result); + + if (out_vpn) + *out_vpn = vpn; + if (out_ac) + *out_ac = NM_ACTIVE_CONNECTION (vpn); + if (out_ip_iface) + *out_ip_iface = nm_vpn_connection_get_ip_iface (vpn); + } else { + NMDevice *device = entry->source.device; + NMActRequest *req; + + if (entry->never_default) + continue; + + if (VTABLE_IS_IP4) + config_result = nm_device_get_ip4_config (device); + else + config_result = nm_device_get_ip6_config (device); + g_assert (config_result); + req = nm_device_get_act_request (device); + g_assert (req); + + if (out_device) + *out_device = device; + if (out_ac) + *out_ac = NM_ACTIVE_CONNECTION (req); + if (out_ip_iface) + *out_ip_iface = nm_device_get_ip_iface (device); + } + break; + } + + return config_result; +} + +NMIP4Config * +nm_default_route_manager_ip4_get_best_config (NMDefaultRouteManager *self, + gboolean ignore_never_default, + const char **out_ip_iface, + NMActiveConnection **out_ac, + NMDevice **out_device, + NMVpnConnection **out_vpn) +{ + return _ipx_get_best_config (&vtable_ip4, + self, + ignore_never_default, + out_ip_iface, + out_ac, + out_device, + out_vpn); +} + +NMIP6Config * +nm_default_route_manager_ip6_get_best_config (NMDefaultRouteManager *self, + gboolean ignore_never_default, + const char **out_ip_iface, + NMActiveConnection **out_ac, + NMDevice **out_device, + NMVpnConnection **out_vpn) +{ + return _ipx_get_best_config (&vtable_ip6, + self, + ignore_never_default, + out_ip_iface, + out_ac, + out_device, + out_vpn); +} + +/***********************************************************************************/ + +static GPtrArray * +_v4_get_entries (NMDefaultRouteManagerPrivate *priv) +{ + return priv->entries_ip4; +} + +static GPtrArray * +_v6_get_entries (NMDefaultRouteManagerPrivate *priv) +{ + return priv->entries_ip6; +} + +static gboolean +_v4_platform_route_delete_default (int ifindex, guint32 metric) +{ + return nm_platform_ip4_route_delete (ifindex, 0, 0, metric); +} + +static gboolean +_v6_platform_route_delete_default (int ifindex, guint32 metric) +{ + return nm_platform_ip6_route_delete (ifindex, in6addr_any, 0, metric); +} + +static guint32 +_v4_route_metric_normalize (guint32 metric) +{ + return metric; +} + +static const VTableIP vtable_ip4 = { + .addr_family = AF_INET, + .get_entries = _v4_get_entries, + .platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip4_route_to_string, + .platform_route_get_all = nm_platform_ip4_route_get_all, + .platform_route_delete_default = _v4_platform_route_delete_default, + .route_metric_normalize = _v4_route_metric_normalize, +}; + +static const VTableIP vtable_ip6 = { + .addr_family = AF_INET6, + .get_entries = _v6_get_entries, + .platform_route_to_string = (const char *(*)(const NMPlatformIPRoute *)) nm_platform_ip6_route_to_string, + .platform_route_get_all = nm_platform_ip6_route_get_all, + .platform_route_delete_default = _v6_platform_route_delete_default, + .route_metric_normalize = nm_utils_ip6_route_metric_normalize, +}; + +/***********************************************************************************/ + +NMDefaultRouteManager * +nm_default_route_manager_get () +{ + if (G_UNLIKELY (!_instance)) { + _instance = NM_DEFAULT_ROUTE_MANAGER (g_object_new (NM_TYPE_DEFAULT_ROUTE_MANAGER, NULL)); + g_object_add_weak_pointer (G_OBJECT (_instance), (gpointer *) &_instance); + } + return _instance; +} + +/***********************************************************************************/ + +static gboolean +_resync_idle_now (NMDefaultRouteManager *self) +{ + gboolean has_v4_changes, has_v6_changes; + gboolean changed = FALSE; + + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + has_v4_changes = priv->resync.has_v4_changes; + has_v6_changes = priv->resync.has_v6_changes; + + _LOGD (0, "resync: sync now (%u) (IPv4 changes: %s, IPv6 changes: %s)", priv->resync.idle_handle, + has_v4_changes ? "yes" : "no", has_v6_changes ? "yes" : "no"); + + priv->resync.has_v4_changes = FALSE; + priv->resync.has_v6_changes = FALSE; + priv->resync.idle_handle = 0; + priv->resync.backoff_wait_time_ms = + priv->resync.backoff_wait_time_ms == 0 + ? 100 + : priv->resync.backoff_wait_time_ms * 2; + + if (has_v4_changes) + changed |= _resync_all (&vtable_ip4, self, NULL, NULL, TRUE); + + if (has_v6_changes) + changed |= _resync_all (&vtable_ip6, self, NULL, NULL, TRUE); + + if (!changed) { + /* Nothing changed: reset the backoff wait time */ + _resync_idle_cancel (self); + } + + return G_SOURCE_REMOVE; +} + +static void +_resync_idle_cancel (NMDefaultRouteManager *self) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + if (priv->resync.idle_handle) { + _LOGD (0, "resync: cancelled (%u)", priv->resync.idle_handle); + g_source_remove (priv->resync.idle_handle); + priv->resync.idle_handle = 0; + } + priv->resync.backoff_wait_time_ms = 0; + priv->resync.has_v4_changes = FALSE; + priv->resync.has_v6_changes = FALSE; +} + +static void +_resync_idle_reschedule (NMDefaultRouteManager *self) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + /* since we react on external changes and readd/remove default routes for + * the interfaces we manage, there could be the erronous situation where two applications + * fight over a certain default route. + * Avoid this, by increasingly wait longer to touch the system (backoff wait time). */ + + if (priv->resync.backoff_wait_time_ms == 0) { + /* for scheduling idle, always reschedule (to process all other events first) */ + if (priv->resync.idle_handle) + g_source_remove (priv->resync.idle_handle); + else + _LOGD (0, "resync: schedule on idle"); + priv->resync.idle_handle = g_idle_add ((GSourceFunc) _resync_idle_now, self); + } else if (!priv->resync.idle_handle) { + priv->resync.idle_handle = g_timeout_add (priv->resync.backoff_wait_time_ms, (GSourceFunc) _resync_idle_now, self); + _LOGD (0, "resync: schedule in %u.%03u seconds (%u)", priv->resync.backoff_wait_time_ms/1000, + priv->resync.backoff_wait_time_ms%1000, priv->resync.idle_handle); + } +} + +static void +_platform_ipx_route_changed_cb (const VTableIP *vtable, + NMDefaultRouteManager *self, + const NMPlatformIPRoute *route) +{ + NMDefaultRouteManagerPrivate *priv; + + if (route && !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { + /* we only care about address changes or changes of default route. */ + return; + } + + priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + if (priv->resync.guard) { + /* callbacks while executing _resync_all() are ignored. */ + return; + } + + if (VTABLE_IS_IP4) + priv->resync.has_v4_changes = TRUE; + else + priv->resync.has_v6_changes = TRUE; + + _resync_idle_reschedule (self); +} + +static void +_platform_ip4_address_changed_cb (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDefaultRouteManager *self) +{ + _platform_ipx_route_changed_cb (&vtable_ip4, self, NULL); +} + +static void +_platform_ip6_address_changed_cb (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDefaultRouteManager *self) +{ + _platform_ipx_route_changed_cb (&vtable_ip6, self, NULL); +} + +static void +_platform_ip4_route_changed_cb (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDefaultRouteManager *self) +{ + _platform_ipx_route_changed_cb (&vtable_ip4, self, platform_object); +} + +static void +_platform_ip6_route_changed_cb (NMPlatform *platform, + int ifindex, + gpointer platform_object, + NMPlatformSignalChangeType change_type, + NMPlatformReason reason, + NMDefaultRouteManager *self) +{ + _platform_ipx_route_changed_cb (&vtable_ip6, self, platform_object); +} + +/***********************************************************************************/ + +static void +nm_default_route_manager_init (NMDefaultRouteManager *self) +{ + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + NMPlatform *platform; + + priv->entries_ip4 = g_ptr_array_new_full (0, (GDestroyNotify) _entry_free); + priv->entries_ip6 = g_ptr_array_new_full (0, (GDestroyNotify) _entry_free); + + platform = nm_platform_get (); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_platform_ip4_address_changed_cb), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_platform_ip6_address_changed_cb), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_platform_ip4_route_changed_cb), self); + g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_platform_ip6_route_changed_cb), self); +} + +static void +dispose (GObject *object) +{ + NMDefaultRouteManager *self = NM_DEFAULT_ROUTE_MANAGER (object); + NMDefaultRouteManagerPrivate *priv = NM_DEFAULT_ROUTE_MANAGER_GET_PRIVATE (self); + + if (priv->entries_ip4) { + g_ptr_array_free (priv->entries_ip4, TRUE); + priv->entries_ip4 = NULL; + } + if (priv->entries_ip6) { + g_ptr_array_free (priv->entries_ip6, TRUE); + priv->entries_ip6 = NULL; + } + + _resync_idle_cancel (self); + + g_signal_handlers_disconnect_by_data (nm_platform_get (), self); + + G_OBJECT_CLASS (nm_default_route_manager_parent_class)->dispose (object); +} + +static void +nm_default_route_manager_class_init (NMDefaultRouteManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (NMDefaultRouteManagerPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; +} + diff --git a/src/nm-default-route-manager.h b/src/nm-default-route-manager.h new file mode 100644 index 00000000..d8e42273 --- /dev/null +++ b/src/nm-default-route-manager.h @@ -0,0 +1,74 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include + +#include "nm-connection.h" +#include "nm-types.h" + +#ifndef __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__ +#define __NETWORKMANAGER_DEFAULT_ROUTE_MANAGER_H__ + + +#define NM_TYPE_DEFAULT_ROUTE_MANAGER (nm_default_route_manager_get_type ()) +#define NM_DEFAULT_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManager)) +#define NM_DEFAULT_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerClass)) +#define NM_IS_DEFAULT_ROUTE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER)) +#define NM_IS_DEFAULT_ROUTE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEFAULT_ROUTE_MANAGER)) +#define NM_DEFAULT_ROUTE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_ROUTE_MANAGER, NMDefaultRouteManagerClass)) + + + +struct _NMDefaultRouteManager { + GObject parent; +}; + +typedef struct { + GObjectClass parent; +} NMDefaultRouteManagerClass; + +GType nm_default_route_manager_get_type (void); + +NMDefaultRouteManager *nm_default_route_manager_get (void); + +void nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *manager, gpointer source); +void nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *manager, gpointer source); + +gboolean nm_default_route_manager_ip4_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection); +gboolean nm_default_route_manager_ip6_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection); + +NMDevice *nm_default_route_manager_ip4_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device); +NMDevice *nm_default_route_manager_ip6_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device); + +NMIP4Config *nm_default_route_manager_ip4_get_best_config (NMDefaultRouteManager *manager, + gboolean ignore_never_default, + const char **out_ip_iface, + NMActiveConnection **out_ac, + NMDevice **out_device, + NMVpnConnection **out_vpn); +NMIP6Config *nm_default_route_manager_ip6_get_best_config (NMDefaultRouteManager *manager, + gboolean ignore_never_default, + const char **out_ip_iface, + NMActiveConnection **out_ac, + NMDevice **out_device, + NMVpnConnection **out_vpn); + +#endif /* NM_DEFAULT_ROUTE_MANAGER_H */ + diff --git a/src/nm-device-glue.h b/src/nm-device-glue.h index 55b7c558..a740b7a7 100644 --- a/src/nm-device-glue.h +++ b/src/nm-device-glue.h @@ -66,12 +66,13 @@ G_END_DECLS #include static const DBusGMethodInfo dbus_glib_nm_device_methods[] = { { (GCallback) impl_device_disconnect, dbus_glib_marshal_nm_device_NONE__POINTER, 0 }, + { (GCallback) impl_device_delete, dbus_glib_marshal_nm_device_NONE__POINTER, 52 }, }; const DBusGObjectInfo dbus_glib_nm_device_object_info = { 1, dbus_glib_nm_device_methods, - 1, -"org.freedesktop.NetworkManager.Device\0Disconnect\0A\0\0\0", + 2, +"org.freedesktop.NetworkManager.Device\0Disconnect\0A\0\0org.freedesktop.NetworkManager.Device\0Delete\0A\0\0\0", "org.freedesktop.NetworkManager.Device\0StateChanged\0\0", "org.freedesktop.NetworkManager.Device\0Udi\0udi\0read\0org.freedesktop.NetworkManager.Device\0Interface\0interface\0read\0org.freedesktop.NetworkManager.Device\0IpInterface\0ip_interface\0read\0org.freedesktop.NetworkManager.Device\0Driver\0driver\0read\0org.freedesktop.NetworkManager.Device\0DriverVersion\0driver_version\0read\0org.freedesktop.NetworkManager.Device\0FirmwareVersion\0firmware_version\0read\0org.freedesktop.NetworkManager.Device\0Capabilities\0capabilities\0read\0org.freedesktop.NetworkManager.Device\0Ip4Address\0ip4_address\0read\0org.freedesktop.NetworkManager.Device\0State\0state\0read\0org.freedesktop.NetworkManager.Device\0StateReason\0state_reason\0read\0org.freedesktop.NetworkManager.Device\0ActiveConnection\0active_connection\0read\0org.freedesktop.NetworkManager.Device\0Ip4Config\0ip4_config\0read\0org.freedesktop.NetworkManager.Device\0Dhcp4Config\0dhcp4_config\0read\0org.freedesktop.NetworkManager.Device\0Ip6Config\0ip6_config\0read\0org.freedesktop.NetworkManager.Device\0Dhcp6Config\0dhcp6_config\0read\0org.freedesktop.NetworkManager.Device\0Managed\0managed\0read\0org.freedesktop.NetworkManager.Device\0Autoconnect\0autoconnect\0readwrite\0org.freedesktop.NetworkManager.Device\0FirmwareMissing\0firmware_missing\0read\0org.freedesktop.NetworkManager.Device\0DeviceType\0device_type\0read\0org.freedesktop.NetworkManager.Device\0AvailableConnections\0available_connections\0read\0org.freedesktop.NetworkManager.Device\0PhysicalPortId\0physical_port_id\0read\0org.freedesktop.NetworkManager.Device\0Mtu\0mtu\0read\0\0" }; diff --git a/src/nm-device-team-glue.h b/src/nm-device-team-glue.h deleted file mode 100644 index 405975c8..00000000 --- a/src/nm-device-team-glue.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ - - -#ifndef __dbus_glib_marshal_nm_device_team_MARSHAL_H__ -#define __dbus_glib_marshal_nm_device_team_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -G_END_DECLS - -#endif /* __dbus_glib_marshal_nm_device_team_MARSHAL_H__ */ - -#include -static const DBusGMethodInfo dbus_glib_nm_device_team_methods[] = { -}; - -const DBusGObjectInfo dbus_glib_nm_device_team_object_info = { 1, - dbus_glib_nm_device_team_methods, - 0, -"\0", -"org.freedesktop.NetworkManager.Device.Team\0PropertiesChanged\0\0", -"org.freedesktop.NetworkManager.Device.Team\0HwAddress\0hw_address\0read\0org.freedesktop.NetworkManager.Device.Team\0Carrier\0carrier\0read\0org.freedesktop.NetworkManager.Device.Team\0Slaves\0slaves\0read\0\0" -}; - diff --git a/src/nm-device-vlan-glue.h b/src/nm-device-vlan-glue.h index c9e51d54..cd1f5580 100644 --- a/src/nm-device-vlan-glue.h +++ b/src/nm-device-vlan-glue.h @@ -68,6 +68,6 @@ const DBusGObjectInfo dbus_glib_nm_device_vlan_object_info = { 1, 0, "\0", "org.freedesktop.NetworkManager.Device.Vlan\0PropertiesChanged\0\0", -"org.freedesktop.NetworkManager.Device.Vlan\0HwAddress\0hw_address\0read\0org.freedesktop.NetworkManager.Device.Vlan\0Carrier\0carrier\0read\0org.freedesktop.NetworkManager.Device.Vlan\0VlanId\0vlan_id\0read\0\0" +"org.freedesktop.NetworkManager.Device.Vlan\0HwAddress\0hw_address\0read\0org.freedesktop.NetworkManager.Device.Vlan\0Carrier\0carrier\0read\0org.freedesktop.NetworkManager.Device.Vlan\0Parent\0parent\0read\0org.freedesktop.NetworkManager.Device.Vlan\0VlanId\0vlan_id\0read\0\0" }; diff --git a/src/nm-dhcp4-config.c b/src/nm-dhcp4-config.c index a405aa87..096cf16d 100644 --- a/src/nm-dhcp4-config.c +++ b/src/nm-dhcp4-config.c @@ -18,10 +18,12 @@ * Copyright (C) 2008 Red Hat, Inc. */ +#include "config.h" + #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-dhcp4-config.h" #include "nm-dhcp4-config-glue.h" @@ -29,14 +31,14 @@ #include "nm-utils.h" -G_DEFINE_TYPE (NMDHCP4Config, nm_dhcp4_config, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, G_TYPE_OBJECT) -#define NM_DHCP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigPrivate)) +#define NM_DHCP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigPrivate)) typedef struct { char *dbus_path; GHashTable *options; -} NMDHCP4ConfigPrivate; +} NMDhcp4ConfigPrivate; enum { @@ -47,14 +49,14 @@ enum { }; -NMDHCP4Config * +NMDhcp4Config * nm_dhcp4_config_new (void) { return NM_DHCP4_CONFIG (g_object_new (NM_TYPE_DHCP4_CONFIG, NULL)); } void -nm_dhcp4_config_add_option (NMDHCP4Config *self, +nm_dhcp4_config_add_option (NMDhcp4Config *self, const char *key, const char *option) { @@ -72,7 +74,7 @@ nm_dhcp4_config_add_option (NMDHCP4Config *self, } void -nm_dhcp4_config_reset (NMDHCP4Config *self) +nm_dhcp4_config_reset (NMDhcp4Config *self) { g_return_if_fail (NM_IS_DHCP4_CONFIG (self)); @@ -81,7 +83,7 @@ nm_dhcp4_config_reset (NMDHCP4Config *self) } const char * -nm_dhcp4_config_get_option (NMDHCP4Config *self, const char *key) +nm_dhcp4_config_get_option (NMDhcp4Config *self, const char *key) { GValue *value; @@ -94,7 +96,7 @@ nm_dhcp4_config_get_option (NMDHCP4Config *self, const char *key) /* Caller owns the list, but not the values in the list */ GSList * -nm_dhcp4_config_list_options (NMDHCP4Config *self) +nm_dhcp4_config_list_options (NMDhcp4Config *self) { GHashTableIter iter; const char *option = NULL; @@ -110,7 +112,7 @@ nm_dhcp4_config_list_options (NMDHCP4Config *self) } const char * -nm_dhcp4_config_get_dbus_path (NMDHCP4Config *self) +nm_dhcp4_config_get_dbus_path (NMDhcp4Config *self) { g_return_val_if_fail (NM_IS_DHCP4_CONFIG (self), NULL); @@ -127,9 +129,9 @@ nm_gvalue_destroy (gpointer data) } static void -nm_dhcp4_config_init (NMDHCP4Config *self) +nm_dhcp4_config_init (NMDhcp4Config *self) { - NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self); + NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (self); static guint32 counter = 0; priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/DHCP4Config/%d", counter++); @@ -141,7 +143,7 @@ nm_dhcp4_config_init (NMDHCP4Config *self) static void finalize (GObject *object) { - NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); + NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); g_free (priv->dbus_path); g_hash_table_destroy (priv->options); @@ -153,7 +155,7 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDHCP4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); + NMDhcp4ConfigPrivate *priv = NM_DHCP4_CONFIG_GET_PRIVATE (object); switch (prop_id) { case PROP_OPTIONS: @@ -166,11 +168,11 @@ get_property (GObject *object, guint prop_id, } static void -nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class) +nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - g_type_class_add_private (config_class, sizeof (NMDHCP4ConfigPrivate)); + g_type_class_add_private (config_class, sizeof (NMDhcp4ConfigPrivate)); /* virtual methods */ object_class->get_property = get_property; @@ -179,11 +181,10 @@ nm_dhcp4_config_class_init (NMDHCP4ConfigClass *config_class) /* properties */ g_object_class_install_property (object_class, PROP_OPTIONS, - g_param_spec_boxed (NM_DHCP4_CONFIG_OPTIONS, - "Options", - "DHCP configuration options returned by the server", + g_param_spec_boxed (NM_DHCP4_CONFIG_OPTIONS, "", "", DBUS_TYPE_G_MAP_OF_VARIANT, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (config_class), diff --git a/src/nm-dhcp4-config.h b/src/nm-dhcp4-config.h index 6eb9ee57..227d4481 100644 --- a/src/nm-dhcp4-config.h +++ b/src/nm-dhcp4-config.h @@ -18,44 +18,46 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#ifndef NM_DHCP4_CONFIG_H -#define NM_DHCP4_CONFIG_H +#ifndef __NETWORKMANAGER_DHCP4_CONFIG_H__ +#define __NETWORKMANAGER_DHCP4_CONFIG_H__ #include #include +#include "nm-types.h" + #define NM_TYPE_DHCP4_CONFIG (nm_dhcp4_config_get_type ()) -#define NM_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP4_CONFIG, NMDHCP4Config)) -#define NM_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigClass)) +#define NM_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4Config)) +#define NM_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass)) #define NM_IS_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP4_CONFIG)) #define NM_IS_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP4_CONFIG)) -#define NM_DHCP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP4_CONFIG, NMDHCP4ConfigClass)) +#define NM_DHCP4_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass)) -typedef struct { +struct _NMDhcp4Config { GObject parent; -} NMDHCP4Config; +}; typedef struct { GObjectClass parent; -} NMDHCP4ConfigClass; +} NMDhcp4ConfigClass; #define NM_DHCP4_CONFIG_OPTIONS "options" GType nm_dhcp4_config_get_type (void); -NMDHCP4Config *nm_dhcp4_config_new (void); +NMDhcp4Config *nm_dhcp4_config_new (void); -const char *nm_dhcp4_config_get_dbus_path (NMDHCP4Config *config); +const char *nm_dhcp4_config_get_dbus_path (NMDhcp4Config *config); -void nm_dhcp4_config_add_option (NMDHCP4Config *config, +void nm_dhcp4_config_add_option (NMDhcp4Config *config, const char *key, const char *option); -void nm_dhcp4_config_reset (NMDHCP4Config *config); +void nm_dhcp4_config_reset (NMDhcp4Config *config); -const char *nm_dhcp4_config_get_option (NMDHCP4Config *config, const char *option); +const char *nm_dhcp4_config_get_option (NMDhcp4Config *config, const char *option); -GSList *nm_dhcp4_config_list_options (NMDHCP4Config *config); +GSList *nm_dhcp4_config_list_options (NMDhcp4Config *config); -#endif /* NM_DHCP4_CONFIG_H */ +#endif /* __NETWORKMANAGER_DHCP4_CONFIG_H__ */ diff --git a/src/nm-dhcp6-config.c b/src/nm-dhcp6-config.c index c50b8fdd..f93e9644 100644 --- a/src/nm-dhcp6-config.c +++ b/src/nm-dhcp6-config.c @@ -18,10 +18,12 @@ * Copyright (C) 2008 Red Hat, Inc. */ +#include "config.h" + #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-dbus-manager.h" #include "nm-dhcp6-config.h" #include "nm-dhcp6-config-glue.h" @@ -29,14 +31,14 @@ #include "nm-utils.h" -G_DEFINE_TYPE (NMDHCP6Config, nm_dhcp6_config, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, G_TYPE_OBJECT) -#define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigPrivate)) +#define NM_DHCP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigPrivate)) typedef struct { char *dbus_path; GHashTable *options; -} NMDHCP6ConfigPrivate; +} NMDhcp6ConfigPrivate; enum { @@ -47,14 +49,14 @@ enum { }; -NMDHCP6Config * +NMDhcp6Config * nm_dhcp6_config_new (void) { return NM_DHCP6_CONFIG (g_object_new (NM_TYPE_DHCP6_CONFIG, NULL)); } void -nm_dhcp6_config_add_option (NMDHCP6Config *self, +nm_dhcp6_config_add_option (NMDhcp6Config *self, const char *key, const char *option) { @@ -72,7 +74,7 @@ nm_dhcp6_config_add_option (NMDHCP6Config *self, } void -nm_dhcp6_config_reset (NMDHCP6Config *self) +nm_dhcp6_config_reset (NMDhcp6Config *self) { g_return_if_fail (NM_IS_DHCP6_CONFIG (self)); @@ -81,7 +83,7 @@ nm_dhcp6_config_reset (NMDHCP6Config *self) } const char * -nm_dhcp6_config_get_option (NMDHCP6Config *self, const char *key) +nm_dhcp6_config_get_option (NMDhcp6Config *self, const char *key) { GValue *value; @@ -94,7 +96,7 @@ nm_dhcp6_config_get_option (NMDHCP6Config *self, const char *key) /* Caller owns the list, but not the values in the list */ GSList * -nm_dhcp6_config_list_options (NMDHCP6Config *self) +nm_dhcp6_config_list_options (NMDhcp6Config *self) { GHashTableIter iter; const char *option = NULL; @@ -110,7 +112,7 @@ nm_dhcp6_config_list_options (NMDHCP6Config *self) } const char * -nm_dhcp6_config_get_dbus_path (NMDHCP6Config *self) +nm_dhcp6_config_get_dbus_path (NMDhcp6Config *self) { g_return_val_if_fail (NM_IS_DHCP6_CONFIG (self), NULL); @@ -127,9 +129,9 @@ nm_gvalue_destroy (gpointer data) } static void -nm_dhcp6_config_init (NMDHCP6Config *self) +nm_dhcp6_config_init (NMDhcp6Config *self) { - NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self); + NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (self); static guint32 counter = 0; priv->dbus_path = g_strdup_printf (NM_DBUS_PATH "/DHCP6Config/%d", counter++); @@ -141,7 +143,7 @@ nm_dhcp6_config_init (NMDHCP6Config *self) static void finalize (GObject *object) { - NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); + NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); g_free (priv->dbus_path); g_hash_table_destroy (priv->options); @@ -153,7 +155,7 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMDHCP6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); + NMDhcp6ConfigPrivate *priv = NM_DHCP6_CONFIG_GET_PRIVATE (object); switch (prop_id) { case PROP_OPTIONS: @@ -166,11 +168,11 @@ get_property (GObject *object, guint prop_id, } static void -nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class) +nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - g_type_class_add_private (config_class, sizeof (NMDHCP6ConfigPrivate)); + g_type_class_add_private (config_class, sizeof (NMDhcp6ConfigPrivate)); /* virtual methods */ object_class->get_property = get_property; @@ -179,11 +181,10 @@ nm_dhcp6_config_class_init (NMDHCP6ConfigClass *config_class) /* properties */ g_object_class_install_property (object_class, PROP_OPTIONS, - g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS, - "Options", - "DHCP configuration options returned by the server", + g_param_spec_boxed (NM_DHCP6_CONFIG_OPTIONS, "", "", DBUS_TYPE_G_MAP_OF_VARIANT, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (config_class), diff --git a/src/nm-dhcp6-config.h b/src/nm-dhcp6-config.h index 2af65607..eaca61b1 100644 --- a/src/nm-dhcp6-config.h +++ b/src/nm-dhcp6-config.h @@ -18,44 +18,46 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#ifndef NM_DHCP6_CONFIG_H -#define NM_DHCP6_CONFIG_H +#ifndef __NETWORKMANAGER_DHCP6_CONFIG_H__ +#define __NETWORKMANAGER_DHCP6_CONFIG_H__ #include #include +#include "nm-types.h" + #define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type ()) -#define NM_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP6_CONFIG, NMDHCP6Config)) -#define NM_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigClass)) +#define NM_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6Config)) +#define NM_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass)) #define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DHCP6_CONFIG)) #define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DHCP6_CONFIG)) -#define NM_DHCP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP6_CONFIG, NMDHCP6ConfigClass)) +#define NM_DHCP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass)) -typedef struct { +struct _NMDhcp6Config { GObject parent; -} NMDHCP6Config; +}; typedef struct { GObjectClass parent; -} NMDHCP6ConfigClass; +} NMDhcp6ConfigClass; #define NM_DHCP6_CONFIG_OPTIONS "options" GType nm_dhcp6_config_get_type (void); -NMDHCP6Config *nm_dhcp6_config_new (void); +NMDhcp6Config *nm_dhcp6_config_new (void); -const char *nm_dhcp6_config_get_dbus_path (NMDHCP6Config *config); +const char *nm_dhcp6_config_get_dbus_path (NMDhcp6Config *config); -void nm_dhcp6_config_add_option (NMDHCP6Config *config, +void nm_dhcp6_config_add_option (NMDhcp6Config *config, const char *key, const char *option); -void nm_dhcp6_config_reset (NMDHCP6Config *config); +void nm_dhcp6_config_reset (NMDhcp6Config *config); -const char *nm_dhcp6_config_get_option (NMDHCP6Config *config, const char *option); +const char *nm_dhcp6_config_get_option (NMDhcp6Config *config, const char *option); -GSList *nm_dhcp6_config_list_options (NMDHCP6Config *self); +GSList *nm_dhcp6_config_list_options (NMDhcp6Config *self); -#endif /* NM_DHCP6_CONFIG_H */ +#endif /* __NETWORKMANAGER_DHCP6_CONFIG_H__ */ diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index f955822b..ae451768 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -19,6 +19,8 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include @@ -30,6 +32,9 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-dbus-manager.h" +#include "nm-device.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" @@ -91,7 +96,7 @@ dump_object_to_props (GObject *object, GHashTable *hash) } static void -dump_dhcp4_to_props (NMDHCP4Config *config, GHashTable *hash) +dump_dhcp4_to_props (NMDhcp4Config *config, GHashTable *hash) { GSList *options, *iter; @@ -107,7 +112,7 @@ dump_dhcp4_to_props (NMDHCP4Config *config, GHashTable *hash) } static void -dump_dhcp6_to_props (NMDHCP6Config *config, GHashTable *hash) +dump_dhcp6_to_props (NMDhcp6Config *config, GHashTable *hash) { GSList *options, *iter; @@ -132,8 +137,8 @@ fill_device_props (NMDevice *device, { NMIP4Config *ip4_config; NMIP6Config *ip6_config; - NMDHCP4Config *dhcp4_config; - NMDHCP6Config *dhcp6_config; + NMDhcp4Config *dhcp4_config; + NMDhcp6Config *dhcp6_config; /* If the action is for a VPN, send the VPN's IP interface instead of the device's */ value_hash_add_str (dev_hash, NMD_DEVICE_PROPS_IP_INTERFACE, nm_device_get_ip_iface (device)); @@ -461,14 +466,18 @@ _dispatcher_call (DispatcherAction action, proxy = dbus_g_proxy_new_for_name (g_connection, NM_DISPATCHER_DBUS_SERVICE, NM_DISPATCHER_DBUS_PATH, - NM_DISPATCHER_DBUS_IFACE); + NM_DISPATCHER_DBUS_INTERFACE); if (!proxy) { nm_log_err (LOGD_DISPATCH, "(%u) could not get dispatcher proxy!", reqid); return FALSE; } if (connection) { - connection_hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_NO_SECRETS); + GVariant *connection_dict; + + connection_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + connection_hash = nm_utils_connection_dict_to_hash (connection_dict); + g_variant_unref (connection_dict); connection_props = value_hash_create (); value_hash_add_object_path (connection_props, diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h index 464f6310..e93816b6 100644 --- a/src/nm-dispatcher.h +++ b/src/nm-dispatcher.h @@ -19,15 +19,13 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ -#ifndef NM_DISPATCHER_H -#define NM_DISPATCHER_H +#ifndef __NETWORKMANAGER_DISPATCHER_H__ +#define __NETWORKMANAGER_DISPATCHER_H__ #include #include -#include "nm-device.h" -#include "nm-ip4-config.h" -#include "nm-ip6-config.h" +#include "nm-types.h" #include "nm-connection.h" typedef enum { @@ -78,4 +76,4 @@ void nm_dispatcher_call_cancel (guint call_id); void nm_dispatcher_init (void); -#endif /* NM_DISPATCHER_H */ +#endif /* __NETWORKMANAGER_DISPATCHER_H__ */ diff --git a/src/nm-enum-types.c b/src/nm-enum-types.c index 95d64a8b..ee1df59f 100644 --- a/src/nm-enum-types.c +++ b/src/nm-enum-types.c @@ -5,27 +5,29 @@ #include "nm-enum-types.h" -#include "nm-config.h" -#include "nm-config-device.h" -#include "nm-device.h" #include "nm-device-bond.h" #include "nm-device-bridge.h" #include "nm-device-ethernet.h" -#include "nm-device-factory.h" -#include "nm-device-generic.h" #include "nm-device-gre.h" #include "nm-device-infiniband.h" #include "nm-device-macvlan.h" -#include "nm-device-private.h" -#include "nm-device-team.h" #include "nm-device-tun.h" #include "nm-device-veth.h" #include "nm-device-vlan.h" #include "nm-device-vxlan.h" -#include "nm-dhcp-client.h" #include "nm-dhcp-dhclient.h" #include "nm-dhcp-dhclient-utils.h" #include "nm-dhcp-dhcpcd.h" +#include "nm-dhcp-systemd.h" +#include "nm-device.h" +#include "nm-device-ethernet-utils.h" +#include "nm-device-factory.h" +#include "nm-device-generic.h" +#include "nm-device-logging.h" +#include "nm-device-private.h" +#include "nm-dhcp-client.h" +#include "nm-dhcp-utils.h" +#include "nm-dhcp-listener.h" #include "nm-dhcp-manager.h" #include "nm-dns-dnsmasq.h" #include "nm-dns-unbound.h" @@ -34,8 +36,6 @@ #include "nm-dns-utils.h" #include "nm-dnsmasq-manager.h" #include "nm-dnsmasq-utils.h" -#include "nm-firewall-manager.h" -#include "nm-logging.h" #include "nm-fake-platform.h" #include "nm-linux-platform.h" #include "nm-platform.h" @@ -45,15 +45,12 @@ #include "nm-fake-rdisc.h" #include "nm-lndp-rdisc.h" #include "nm-rdisc.h" -#include "nm-posix-signals.h" #include "nm-ppp-manager.h" #include "nm-ppp-status.h" #include "nm-agent-manager.h" #include "nm-inotify-helper.h" #include "nm-secret-agent.h" #include "nm-settings-connection.h" -#include "nm-settings-error.h" -#include "nm-settings-utils.h" #include "nm-settings.h" #include "nm-system-config-interface.h" #include "common.h" @@ -73,19 +70,25 @@ #include "nm-vpn-service.h" #include "nm-activation-request.h" #include "nm-active-connection.h" +#include "nm-config.h" #include "nm-connection-provider.h" #include "nm-connectivity.h" #include "nm-dbus-manager.h" #include "nm-dcb.h" +#include "nm-default-route-manager.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" #include "nm-dispatcher.h" +#include "nm-firewall-manager.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -#include "nm-manager-auth.h" +#include "nm-logging.h" +#include "nm-auth-manager.h" #include "nm-auth-subject.h" +#include "nm-auth-utils.h" #include "nm-manager.h" #include "nm-policy.h" +#include "nm-posix-signals.h" #include "nm-properties-changed-signal.h" #include "nm-rfkill-manager.h" #include "nm-session-monitor.h" @@ -97,20 +100,20 @@ #include "nm-device-wimax.h" GType -nm_device_error_get_type (void) +nm_vlan_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_DEVICE_ERROR_CONNECTION_ACTIVATING, "NM_DEVICE_ERROR_CONNECTION_ACTIVATING", "ConnectionActivating" }, - { NM_DEVICE_ERROR_CONNECTION_INVALID, "NM_DEVICE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_DEVICE_ERROR_NOT_ACTIVE, "NM_DEVICE_ERROR_NOT_ACTIVE", "NotActive" }, + { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" }, + { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, + { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDeviceError"), values); + g_enum_register_static (g_intern_static_string ("NMVlanError"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -128,6 +131,8 @@ nm_unmanaged_flags_get_type (void) { NM_UNMANAGED_DEFAULT, "NM_UNMANAGED_DEFAULT", "nm-unmanaged-default" }, { NM_UNMANAGED_INTERNAL, "NM_UNMANAGED_INTERNAL", "nm-unmanaged-internal" }, { NM_UNMANAGED_USER, "NM_UNMANAGED_USER", "nm-unmanaged-user" }, + { NM_UNMANAGED_PARENT, "NM_UNMANAGED_PARENT", "nm-unmanaged-parent" }, + { NM_UNMANAGED_EXTERNAL_DOWN, "NM_UNMANAGED_EXTERNAL_DOWN", "nm-unmanaged-external-down" }, { __NM_UNMANAGED_LAST, "__NM_UNMANAGED_LAST", "--nm-unmanaged-last" }, { NM_UNMANAGED_LAST, "NM_UNMANAGED_LAST", "nm-unmanaged-last" }, { 0, NULL, NULL } @@ -140,146 +145,6 @@ nm_unmanaged_flags_get_type (void) return g_define_type_id__volatile; } GType -nm_bond_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_BOND_ERROR_CONNECTION_NOT_BOND, "NM_BOND_ERROR_CONNECTION_NOT_BOND", "ConnectionNotBond" }, - { NM_BOND_ERROR_CONNECTION_INVALID, "NM_BOND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_BOND_ERROR_CONNECTION_INCOMPATIBLE, "NM_BOND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMBondError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_bridge_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE, "NM_BRIDGE_ERROR_CONNECTION_NOT_BRIDGE", "ConnectionNotBridge" }, - { NM_BRIDGE_ERROR_CONNECTION_INVALID, "NM_BRIDGE_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE, "NM_BRIDGE_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMBridgeError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_ethernet_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED, "NM_ETHERNET_ERROR_CONNECTION_NOT_WIRED", "ConnectionNotWired" }, - { NM_ETHERNET_ERROR_CONNECTION_INVALID, "NM_ETHERNET_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE, "NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMEthernetError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_device_generic_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_DEVICE_GENERIC_ERROR_CONNECTION_NOT_GENERIC, "NM_DEVICE_GENERIC_ERROR_CONNECTION_NOT_GENERIC", "ConnectionNotGeneric" }, - { NM_DEVICE_GENERIC_ERROR_CONNECTION_INVALID, "NM_DEVICE_GENERIC_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_DEVICE_GENERIC_ERROR_CONNECTION_INCOMPATIBLE, "NM_DEVICE_GENERIC_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDeviceGenericError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_infiniband_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND, "NM_INFINIBAND_ERROR_CONNECTION_NOT_INFINIBAND", "ConnectionNotInfiniband" }, - { NM_INFINIBAND_ERROR_CONNECTION_INVALID, "NM_INFINIBAND_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE, "NM_INFINIBAND_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMInfinibandError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_team_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_TEAM_ERROR_CONNECTION_NOT_TEAM, "NM_TEAM_ERROR_CONNECTION_NOT_TEAM", "ConnectionNotTeam" }, - { NM_TEAM_ERROR_CONNECTION_INVALID, "NM_TEAM_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_TEAM_ERROR_CONNECTION_INCOMPATIBLE, "NM_TEAM_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMTeamError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_vlan_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_VLAN_ERROR_CONNECTION_NOT_VLAN, "NM_VLAN_ERROR_CONNECTION_NOT_VLAN", "ConnectionNotVlan" }, - { NM_VLAN_ERROR_CONNECTION_INVALID, "NM_VLAN_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, "NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMVlanError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType nm_dhcp_state_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -287,75 +152,18 @@ nm_dhcp_state_get_type (void) if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { DHC_NBI, "DHC_NBI", "nbi" }, - { DHC_PREINIT, "DHC_PREINIT", "preinit" }, - { DHC_PREINIT6, "DHC_PREINIT6", "preinit6" }, - { DHC_BOUND4, "DHC_BOUND4", "bound4" }, - { DHC_BOUND6, "DHC_BOUND6", "bound6" }, - { DHC_IPV4LL, "DHC_IPV4LL", "ipv4ll" }, - { DHC_RENEW4, "DHC_RENEW4", "renew4" }, - { DHC_RENEW6, "DHC_RENEW6", "renew6" }, - { DHC_REBOOT, "DHC_REBOOT", "reboot" }, - { DHC_REBIND4, "DHC_REBIND4", "rebind4" }, - { DHC_REBIND6, "DHC_REBIND6", "rebind6" }, - { DHC_DEPREF6, "DHC_DEPREF6", "depref6" }, - { DHC_STOP, "DHC_STOP", "stop" }, - { DHC_STOP6, "DHC_STOP6", "stop6" }, - { DHC_MEDIUM, "DHC_MEDIUM", "medium" }, - { DHC_TIMEOUT, "DHC_TIMEOUT", "timeout" }, - { DHC_FAIL, "DHC_FAIL", "fail" }, - { DHC_EXPIRE, "DHC_EXPIRE", "expire" }, - { DHC_EXPIRE6, "DHC_EXPIRE6", "expire6" }, - { DHC_RELEASE, "DHC_RELEASE", "release" }, - { DHC_RELEASE6, "DHC_RELEASE6", "release6" }, - { DHC_START, "DHC_START", "start" }, - { DHC_ABEND, "DHC_ABEND", "abend" }, - { DHC_END, "DHC_END", "end" }, - { DHC_END_OPTIONS, "DHC_END_OPTIONS", "end-options" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDHCPState"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_dhcp_manager_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_DHCP_MANAGER_ERROR_BAD_CLIENT, "NM_DHCP_MANAGER_ERROR_BAD_CLIENT", "BadClient" }, - { NM_DHCP_MANAGER_ERROR_INTERNAL, "NM_DHCP_MANAGER_ERROR_INTERNAL", "InternalError" }, + { NM_DHCP_STATE_UNKNOWN, "NM_DHCP_STATE_UNKNOWN", "nm-dhcp-state-unknown" }, + { NM_DHCP_STATE_BOUND, "NM_DHCP_STATE_BOUND", "nm-dhcp-state-bound" }, + { NM_DHCP_STATE_TIMEOUT, "NM_DHCP_STATE_TIMEOUT", "nm-dhcp-state-timeout" }, + { NM_DHCP_STATE_DONE, "NM_DHCP_STATE_DONE", "nm-dhcp-state-done" }, + { NM_DHCP_STATE_EXPIRE, "NM_DHCP_STATE_EXPIRE", "nm-dhcp-state-expire" }, + { NM_DHCP_STATE_FAIL, "NM_DHCP_STATE_FAIL", "nm-dhcp-state-fail" }, + { __NM_DHCP_STATE_MAX, "__NM_DHCP_STATE_MAX", "--nm-dhcp-state-max" }, + { NM_DHCP_STATE_MAX, "NM_DHCP_STATE_MAX", "nm-dhcp-state-max" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDHCPManagerError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_dns_manager_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_DNS_MANAGER_ERROR_SYSTEM, "NM_DNS_MANAGER_ERROR_SYSTEM", "system" }, - { NM_DNS_MANAGER_ERROR_INVALID_NAMESERVER, "NM_DNS_MANAGER_ERROR_INVALID_NAMESERVER", "invalid-nameserver" }, - { NM_DNS_MANAGER_ERROR_INVALID_HOST, "NM_DNS_MANAGER_ERROR_INVALID_HOST", "invalid-host" }, - { NM_DNS_MANAGER_ERROR_INVALID_ID, "NM_DNS_MANAGER_ERROR_INVALID_ID", "invalid-id" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDnsManagerError"), values); + g_enum_register_static (g_intern_static_string ("NMDhcpState"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -422,25 +230,6 @@ nm_dns_masq_status_get_type (void) return g_define_type_id__volatile; } GType -nm_logging_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_LOGGING_ERROR_UNKNOWN_LEVEL, "NM_LOGGING_ERROR_UNKNOWN_LEVEL", "UnknownLevel" }, - { NM_LOGGING_ERROR_UNKNOWN_DOMAIN, "NM_LOGGING_ERROR_UNKNOWN_DOMAIN", "UnknownDomain" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMLoggingError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType nm_platform_error_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -485,47 +274,6 @@ nm_platform_reason_get_type (void) return g_define_type_id__volatile; } GType -nm_link_type_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_LINK_TYPE_NONE, "NM_LINK_TYPE_NONE", "none" }, - { NM_LINK_TYPE_UNKNOWN, "NM_LINK_TYPE_UNKNOWN", "unknown" }, - { NM_LINK_TYPE_ETHERNET, "NM_LINK_TYPE_ETHERNET", "ethernet" }, - { NM_LINK_TYPE_INFINIBAND, "NM_LINK_TYPE_INFINIBAND", "infiniband" }, - { NM_LINK_TYPE_OLPC_MESH, "NM_LINK_TYPE_OLPC_MESH", "olpc-mesh" }, - { NM_LINK_TYPE_WIFI, "NM_LINK_TYPE_WIFI", "wifi" }, - { NM_LINK_TYPE_WWAN_ETHERNET, "NM_LINK_TYPE_WWAN_ETHERNET", "wwan-ethernet" }, - { NM_LINK_TYPE_WIMAX, "NM_LINK_TYPE_WIMAX", "wimax" }, - { NM_LINK_TYPE_DUMMY, "NM_LINK_TYPE_DUMMY", "dummy" }, - { NM_LINK_TYPE_GRE, "NM_LINK_TYPE_GRE", "gre" }, - { NM_LINK_TYPE_GRETAP, "NM_LINK_TYPE_GRETAP", "gretap" }, - { NM_LINK_TYPE_IFB, "NM_LINK_TYPE_IFB", "ifb" }, - { NM_LINK_TYPE_LOOPBACK, "NM_LINK_TYPE_LOOPBACK", "loopback" }, - { NM_LINK_TYPE_MACVLAN, "NM_LINK_TYPE_MACVLAN", "macvlan" }, - { NM_LINK_TYPE_MACVTAP, "NM_LINK_TYPE_MACVTAP", "macvtap" }, - { NM_LINK_TYPE_OPENVSWITCH, "NM_LINK_TYPE_OPENVSWITCH", "openvswitch" }, - { NM_LINK_TYPE_TAP, "NM_LINK_TYPE_TAP", "tap" }, - { NM_LINK_TYPE_TUN, "NM_LINK_TYPE_TUN", "tun" }, - { NM_LINK_TYPE_VETH, "NM_LINK_TYPE_VETH", "veth" }, - { NM_LINK_TYPE_VLAN, "NM_LINK_TYPE_VLAN", "vlan" }, - { NM_LINK_TYPE_VXLAN, "NM_LINK_TYPE_VXLAN", "vxlan" }, - { NM_LINK_TYPE_BRIDGE, "NM_LINK_TYPE_BRIDGE", "bridge" }, - { NM_LINK_TYPE_BOND, "NM_LINK_TYPE_BOND", "bond" }, - { NM_LINK_TYPE_TEAM, "NM_LINK_TYPE_TEAM", "team" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMLinkType"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType nm_platform_signal_change_type_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -546,27 +294,20 @@ nm_platform_signal_change_type_get_type (void) return g_define_type_id__volatile; } GType -nm_platform_source_get_type (void) +nm_platform_get_route_mode_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_PLATFORM_SOURCE_UNKNOWN, "NM_PLATFORM_SOURCE_UNKNOWN", "unknown" }, - { NM_PLATFORM_SOURCE_KERNEL, "NM_PLATFORM_SOURCE_KERNEL", "kernel" }, - { NM_PLATFORM_SOURCE_SHARED, "NM_PLATFORM_SOURCE_SHARED", "shared" }, - { NM_PLATFORM_SOURCE_IP4LL, "NM_PLATFORM_SOURCE_IP4LL", "ip4ll" }, - { NM_PLATFORM_SOURCE_PPP, "NM_PLATFORM_SOURCE_PPP", "ppp" }, - { NM_PLATFORM_SOURCE_WWAN, "NM_PLATFORM_SOURCE_WWAN", "wwan" }, - { NM_PLATFORM_SOURCE_VPN, "NM_PLATFORM_SOURCE_VPN", "vpn" }, - { NM_PLATFORM_SOURCE_DHCP, "NM_PLATFORM_SOURCE_DHCP", "dhcp" }, - { NM_PLATFORM_SOURCE_RDISC, "NM_PLATFORM_SOURCE_RDISC", "rdisc" }, - { NM_PLATFORM_SOURCE_USER, "NM_PLATFORM_SOURCE_USER", "user" }, + { NM_PLATFORM_GET_ROUTE_MODE_ALL, "NM_PLATFORM_GET_ROUTE_MODE_ALL", "all" }, + { NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, "NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT", "no-default" }, + { NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT, "NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT", "only-default" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMPlatformSource"), values); + g_enum_register_static (g_intern_static_string ("NMPlatformGetRouteMode"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -629,6 +370,7 @@ nm_rdisc_config_map_get_type (void) { NM_RDISC_CONFIG_DNS_SERVERS, "NM_RDISC_CONFIG_DNS_SERVERS", "dns-servers" }, { NM_RDISC_CONFIG_DNS_DOMAINS, "NM_RDISC_CONFIG_DNS_DOMAINS", "dns-domains" }, { NM_RDISC_CONFIG_HOP_LIMIT, "NM_RDISC_CONFIG_HOP_LIMIT", "hop-limit" }, + { NM_RDISC_CONFIG_MTU, "NM_RDISC_CONFIG_MTU", "mtu" }, { 0, NULL, NULL } }; GType g_define_type_id = @@ -670,77 +412,23 @@ nm_ppp_status_get_type (void) return g_define_type_id__volatile; } GType -nm_agent_manager_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN", "SenderUnknown" }, - { NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, - { NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND", "SessionNotFound" }, - { NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER", "InvalidIdentifier" }, - { NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NM_AGENT_MANAGER_ERROR_NOT_REGISTERED", "NotRegistered" }, - { NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR", "InternalError" }, - { NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NM_AGENT_MANAGER_ERROR_NO_SECRETS", "NoSecrets" }, - { NM_AGENT_MANAGER_ERROR_USER_CANCELED, "NM_AGENT_MANAGER_ERROR_USER_CANCELED", "UserCanceled" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMAgentManagerError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_secret_agent_capabilities_get_type (void) +nm_settings_connection_flags_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { - static const GEnumValue values[] = { - { NM_SECRET_AGENT_CAPABILITY_NONE, "NM_SECRET_AGENT_CAPABILITY_NONE", "none" }, - { NM_SECRET_AGENT_CAPABILITY_VPN_HINTS, "NM_SECRET_AGENT_CAPABILITY_VPN_HINTS", "vpn-hints" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMSecretAgentCapabilities"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_settings_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_SETTINGS_ERROR_GENERAL, "NM_SETTINGS_ERROR_GENERAL", "GeneralError" }, - { NM_SETTINGS_ERROR_INVALID_CONNECTION, "NM_SETTINGS_ERROR_INVALID_CONNECTION", "InvalidConnection" }, - { NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "NM_SETTINGS_ERROR_READ_ONLY_CONNECTION", "ReadOnlyConnection" }, - { NM_SETTINGS_ERROR_INTERNAL_ERROR, "NM_SETTINGS_ERROR_INTERNAL_ERROR", "InternalError" }, - { NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE", "SecretsUnavailable" }, - { NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED", "SecretsRequestCanceled" }, - { NM_SETTINGS_ERROR_PERMISSION_DENIED, "NM_SETTINGS_ERROR_PERMISSION_DENIED", "PermissionDenied" }, - { NM_SETTINGS_ERROR_INVALID_SETTING, "NM_SETTINGS_ERROR_INVALID_SETTING", "InvalidSetting" }, - { NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED", "AddNotSupported" }, - { NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED", "UpdateNotSupported" }, - { NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED", "DeleteNotSupported" }, - { NM_SETTINGS_ERROR_ADD_FAILED, "NM_SETTINGS_ERROR_ADD_FAILED", "AddFailed" }, - { NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED", "SaveHostnameNotSupported" }, - { NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED", "SaveHostnameFailed" }, - { NM_SETTINGS_ERROR_HOSTNAME_INVALID, "NM_SETTINGS_ERROR_HOSTNAME_INVALID", "HostnameInvalid" }, - { NM_SETTINGS_ERROR_UUID_EXISTS, "NM_SETTINGS_ERROR_UUID_EXISTS", "UuidExists" }, + static const GFlagsValue values[] = { + { NM_SETTINGS_CONNECTION_FLAGS_NONE, "NM_SETTINGS_CONNECTION_FLAGS_NONE", "nm-settings-connection-flags-none" }, + { NM_SETTINGS_CONNECTION_FLAGS_UNSAVED, "NM_SETTINGS_CONNECTION_FLAGS_UNSAVED", "nm-settings-connection-flags-unsaved" }, + { NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, "NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED", "nm-settings-connection-flags-nm-generated" }, + { NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, "NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED", "nm-settings-connection-flags-nm-generated-assumed" }, + { __NM_SETTINGS_CONNECTION_FLAGS_LAST, "__NM_SETTINGS_CONNECTION_FLAGS_LAST", "--nm-settings-connection-flags-last" }, + { NM_SETTINGS_CONNECTION_FLAGS_ALL, "NM_SETTINGS_CONNECTION_FLAGS_ALL", "nm-settings-connection-flags-all" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMSettingsError"), values); + g_flags_register_static (g_intern_static_string ("NMSettingsConnectionFlags"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -832,49 +520,6 @@ nm_opt_type_get_type (void) return g_define_type_id__volatile; } GType -nm_vpn_manager_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE", "BaseDeviceNotActive" }, - { NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "NM_VPN_MANAGER_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "NM_VPN_MANAGER_ERROR_SERVICE_INVALID", "ServiceInvalid" }, - { NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, "NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED", "ServiceStartFailed" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMVPNManagerError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType -nm_dcb_error_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) - { - static const GEnumValue values[] = { - { NM_DCB_ERROR_UNKNOWN, "NM_DCB_ERROR_UNKNOWN", "unknown" }, - { NM_DCB_ERROR_INTERNAL, "NM_DCB_ERROR_INTERNAL", "internal" }, - { NM_DCB_ERROR_BAD_CONFIG, "NM_DCB_ERROR_BAD_CONFIG", "bad-config" }, - { NM_DCB_ERROR_HELPER_NOT_FOUND, "NM_DCB_ERROR_HELPER_NOT_FOUND", "helper-not-found" }, - { NM_DCB_ERROR_HELPER_FAILED, "NM_DCB_ERROR_HELPER_FAILED", "helper-failed" }, - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMDcbError"), values); - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} -GType nm_dispatcher_action_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; @@ -903,51 +548,41 @@ nm_dispatcher_action_get_type (void) return g_define_type_id__volatile; } GType -nm_auth_call_result_get_type (void) +nm_auth_subject_type_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_AUTH_CALL_RESULT_UNKNOWN, "NM_AUTH_CALL_RESULT_UNKNOWN", "unknown" }, - { NM_AUTH_CALL_RESULT_YES, "NM_AUTH_CALL_RESULT_YES", "yes" }, - { NM_AUTH_CALL_RESULT_AUTH, "NM_AUTH_CALL_RESULT_AUTH", "auth" }, - { NM_AUTH_CALL_RESULT_NO, "NM_AUTH_CALL_RESULT_NO", "no" }, + { NM_AUTH_SUBJECT_TYPE_INVALID, "NM_AUTH_SUBJECT_TYPE_INVALID", "invalid" }, + { NM_AUTH_SUBJECT_TYPE_INTERNAL, "NM_AUTH_SUBJECT_TYPE_INTERNAL", "internal" }, + { NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS, "NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS", "unix-process" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMAuthCallResult"), values); + g_enum_register_static (g_intern_static_string ("NMAuthSubjectType"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } return g_define_type_id__volatile; } GType -nm_manager_error_get_type (void) +nm_auth_call_result_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "NM_MANAGER_ERROR_UNKNOWN_CONNECTION", "UnknownConnection" }, - { NM_MANAGER_ERROR_UNKNOWN_DEVICE, "NM_MANAGER_ERROR_UNKNOWN_DEVICE", "UnknownDevice" }, - { NM_MANAGER_ERROR_UNMANAGED_DEVICE, "NM_MANAGER_ERROR_UNMANAGED_DEVICE", "UnmanagedDevice" }, - { NM_MANAGER_ERROR_SYSTEM_CONNECTION, "NM_MANAGER_ERROR_SYSTEM_CONNECTION", "SystemConnection" }, - { NM_MANAGER_ERROR_PERMISSION_DENIED, "NM_MANAGER_ERROR_PERMISSION_DENIED", "PermissionDenied" }, - { NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE", "ConnectionNotActive" }, - { NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE", "AlreadyAsleepOrAwake" }, - { NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED", "AlreadyEnabledOrDisabled" }, - { NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, "NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE", "UnsupportedConnectionType" }, - { NM_MANAGER_ERROR_DEPENDENCY_FAILED, "NM_MANAGER_ERROR_DEPENDENCY_FAILED", "DependencyFailed" }, - { NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED, "NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED", "AutoconnectNotAllowed" }, - { NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, "NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE", "ConnectionAlreadyActive" }, - { NM_MANAGER_ERROR_INTERNAL, "NM_MANAGER_ERROR_INTERNAL", "Internal" }, + { NM_AUTH_CALL_RESULT_UNKNOWN, "NM_AUTH_CALL_RESULT_UNKNOWN", "unknown" }, + { NM_AUTH_CALL_RESULT_YES, "NM_AUTH_CALL_RESULT_YES", "yes" }, + { NM_AUTH_CALL_RESULT_AUTH, "NM_AUTH_CALL_RESULT_AUTH", "auth" }, + { NM_AUTH_CALL_RESULT_NO, "NM_AUTH_CALL_RESULT_NO", "no" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMManagerError"), values); + g_enum_register_static (g_intern_static_string ("NMAuthCallResult"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } @@ -996,42 +631,68 @@ nm_rf_kill_type_get_type (void) return g_define_type_id__volatile; } GType -nm_session_monitor_error_get_type (void) +nm_ip_config_source_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_SESSION_MONITOR_ERROR_IO_ERROR, "NM_SESSION_MONITOR_ERROR_IO_ERROR", "IOError" }, - { NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE", "MalformedDatabase" }, - { NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "NM_SESSION_MONITOR_ERROR_UNKNOWN_USER", "UnknownUser" }, - { NM_SESSION_MONITOR_ERROR_NO_DATABASE, "NM_SESSION_MONITOR_ERROR_NO_DATABASE", "NoDatabase" }, + { NM_IP_CONFIG_SOURCE_UNKNOWN, "NM_IP_CONFIG_SOURCE_UNKNOWN", "unknown" }, + { NM_IP_CONFIG_SOURCE_KERNEL, "NM_IP_CONFIG_SOURCE_KERNEL", "kernel" }, + { NM_IP_CONFIG_SOURCE_SHARED, "NM_IP_CONFIG_SOURCE_SHARED", "shared" }, + { NM_IP_CONFIG_SOURCE_IP4LL, "NM_IP_CONFIG_SOURCE_IP4LL", "ip4ll" }, + { NM_IP_CONFIG_SOURCE_PPP, "NM_IP_CONFIG_SOURCE_PPP", "ppp" }, + { NM_IP_CONFIG_SOURCE_WWAN, "NM_IP_CONFIG_SOURCE_WWAN", "wwan" }, + { NM_IP_CONFIG_SOURCE_VPN, "NM_IP_CONFIG_SOURCE_VPN", "vpn" }, + { NM_IP_CONFIG_SOURCE_DHCP, "NM_IP_CONFIG_SOURCE_DHCP", "dhcp" }, + { NM_IP_CONFIG_SOURCE_RDISC, "NM_IP_CONFIG_SOURCE_RDISC", "rdisc" }, + { NM_IP_CONFIG_SOURCE_USER, "NM_IP_CONFIG_SOURCE_USER", "user" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMSessionMonitorError"), values); + g_enum_register_static (g_intern_static_string ("NMIPConfigSource"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } return g_define_type_id__volatile; } GType -nm_wimax_error_get_type (void) +nm_link_type_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { static const GEnumValue values[] = { - { NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX, "NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX", "ConnectionNotWimax" }, - { NM_WIMAX_ERROR_CONNECTION_INVALID, "NM_WIMAX_ERROR_CONNECTION_INVALID", "ConnectionInvalid" }, - { NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" }, - { NM_WIMAX_ERROR_NSP_NOT_FOUND, "NM_WIMAX_ERROR_NSP_NOT_FOUND", "NspNotFound" }, + { NM_LINK_TYPE_NONE, "NM_LINK_TYPE_NONE", "none" }, + { NM_LINK_TYPE_UNKNOWN, "NM_LINK_TYPE_UNKNOWN", "unknown" }, + { NM_LINK_TYPE_ETHERNET, "NM_LINK_TYPE_ETHERNET", "ethernet" }, + { NM_LINK_TYPE_INFINIBAND, "NM_LINK_TYPE_INFINIBAND", "infiniband" }, + { NM_LINK_TYPE_OLPC_MESH, "NM_LINK_TYPE_OLPC_MESH", "olpc-mesh" }, + { NM_LINK_TYPE_WIFI, "NM_LINK_TYPE_WIFI", "wifi" }, + { NM_LINK_TYPE_WWAN_ETHERNET, "NM_LINK_TYPE_WWAN_ETHERNET", "wwan-ethernet" }, + { NM_LINK_TYPE_WIMAX, "NM_LINK_TYPE_WIMAX", "wimax" }, + { NM_LINK_TYPE_DUMMY, "NM_LINK_TYPE_DUMMY", "dummy" }, + { NM_LINK_TYPE_GRE, "NM_LINK_TYPE_GRE", "gre" }, + { NM_LINK_TYPE_GRETAP, "NM_LINK_TYPE_GRETAP", "gretap" }, + { NM_LINK_TYPE_IFB, "NM_LINK_TYPE_IFB", "ifb" }, + { NM_LINK_TYPE_LOOPBACK, "NM_LINK_TYPE_LOOPBACK", "loopback" }, + { NM_LINK_TYPE_MACVLAN, "NM_LINK_TYPE_MACVLAN", "macvlan" }, + { NM_LINK_TYPE_MACVTAP, "NM_LINK_TYPE_MACVTAP", "macvtap" }, + { NM_LINK_TYPE_OPENVSWITCH, "NM_LINK_TYPE_OPENVSWITCH", "openvswitch" }, + { NM_LINK_TYPE_TAP, "NM_LINK_TYPE_TAP", "tap" }, + { NM_LINK_TYPE_TUN, "NM_LINK_TYPE_TUN", "tun" }, + { NM_LINK_TYPE_VETH, "NM_LINK_TYPE_VETH", "veth" }, + { NM_LINK_TYPE_VLAN, "NM_LINK_TYPE_VLAN", "vlan" }, + { NM_LINK_TYPE_VXLAN, "NM_LINK_TYPE_VXLAN", "vxlan" }, + { NM_LINK_TYPE_BRIDGE, "NM_LINK_TYPE_BRIDGE", "bridge" }, + { NM_LINK_TYPE_BOND, "NM_LINK_TYPE_BOND", "bond" }, + { NM_LINK_TYPE_TEAM, "NM_LINK_TYPE_TEAM", "team" }, { 0, NULL, NULL } }; GType g_define_type_id = - g_enum_register_static (g_intern_static_string ("NMWimaxError"), values); + g_enum_register_static (g_intern_static_string ("NMLinkType"), values); g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } diff --git a/src/nm-enum-types.h b/src/nm-enum-types.h index 2bf6c734..01d7bb44 100644 --- a/src/nm-enum-types.h +++ b/src/nm-enum-types.h @@ -6,51 +6,30 @@ #ifndef __NM_ENUM_TYPES_H__ #define __NM_ENUM_TYPES_H__ +#include #include G_BEGIN_DECLS -GType nm_device_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_DEVICE_ERROR (nm_device_error_get_type ()) -GType nm_unmanaged_flags_get_type (void) G_GNUC_CONST; -#define NM_TYPE_UNMANAGED_FLAGS (nm_unmanaged_flags_get_type ()) -GType nm_bond_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_BOND_ERROR (nm_bond_error_get_type ()) -GType nm_bridge_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_BRIDGE_ERROR (nm_bridge_error_get_type ()) -GType nm_ethernet_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ()) -GType nm_device_generic_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_DEVICE_GENERIC_ERROR (nm_device_generic_error_get_type ()) -GType nm_infiniband_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_INFINIBAND_ERROR (nm_infiniband_error_get_type ()) -GType nm_team_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_TEAM_ERROR (nm_team_error_get_type ()) GType nm_vlan_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_VLAN_ERROR (nm_vlan_error_get_type ()) +GType nm_unmanaged_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_UNMANAGED_FLAGS (nm_unmanaged_flags_get_type ()) GType nm_dhcp_state_get_type (void) G_GNUC_CONST; #define NM_TYPE_DHCP_STATE (nm_dhcp_state_get_type ()) -GType nm_dhcp_manager_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_DHCP_MANAGER_ERROR (nm_dhcp_manager_error_get_type ()) -GType nm_dns_manager_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_DNS_MANAGER_ERROR (nm_dns_manager_error_get_type ()) GType nm_dns_ip_config_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_DNS_IP_CONFIG_TYPE (nm_dns_ip_config_type_get_type ()) GType nm_dns_manager_resolv_conf_mode_get_type (void) G_GNUC_CONST; #define NM_TYPE_DNS_MANAGER_RESOLV_CONF_MODE (nm_dns_manager_resolv_conf_mode_get_type ()) GType nm_dns_masq_status_get_type (void) G_GNUC_CONST; #define NM_TYPE_DNS_MASQ_STATUS (nm_dns_masq_status_get_type ()) -GType nm_logging_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_LOGGING_ERROR (nm_logging_error_get_type ()) GType nm_platform_error_get_type (void) G_GNUC_CONST; #define NM_TYPE_PLATFORM_ERROR (nm_platform_error_get_type ()) GType nm_platform_reason_get_type (void) G_GNUC_CONST; #define NM_TYPE_PLATFORM_REASON (nm_platform_reason_get_type ()) -GType nm_link_type_get_type (void) G_GNUC_CONST; -#define NM_TYPE_LINK_TYPE (nm_link_type_get_type ()) GType nm_platform_signal_change_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_PLATFORM_SIGNAL_CHANGE_TYPE (nm_platform_signal_change_type_get_type ()) -GType nm_platform_source_get_type (void) G_GNUC_CONST; -#define NM_TYPE_PLATFORM_SOURCE (nm_platform_source_get_type ()) +GType nm_platform_get_route_mode_get_type (void) G_GNUC_CONST; +#define NM_TYPE_PLATFORM_GET_ROUTE_MODE (nm_platform_get_route_mode_get_type ()) GType nm_rdisc_dhcp_level_get_type (void) G_GNUC_CONST; #define NM_TYPE_RDISC_DHCP_LEVEL (nm_rdisc_dhcp_level_get_type ()) GType nm_rdisc_preference_get_type (void) G_GNUC_CONST; @@ -59,12 +38,8 @@ GType nm_rdisc_config_map_get_type (void) G_GNUC_CONST; #define NM_TYPE_RDISC_CONFIG_MAP (nm_rdisc_config_map_get_type ()) GType nm_ppp_status_get_type (void) G_GNUC_CONST; #define NM_TYPE_PPP_STATUS (nm_ppp_status_get_type ()) -GType nm_agent_manager_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) -GType nm_secret_agent_capabilities_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SECRET_AGENT_CAPABILITIES (nm_secret_agent_capabilities_get_type ()) -GType nm_settings_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) +GType nm_settings_connection_flags_get_type (void) G_GNUC_CONST; +#define NM_TYPE_SETTINGS_CONNECTION_FLAGS (nm_settings_connection_flags_get_type ()) GType nm_system_config_interface_capabilities_get_type (void) G_GNUC_CONST; #define NM_TYPE_SYSTEM_CONFIG_INTERFACE_CAPABILITIES (nm_system_config_interface_capabilities_get_type ()) GType nm_system_config_interface_prop_get_type (void) G_GNUC_CONST; @@ -73,24 +48,20 @@ GType nm_ap_support_get_type (void) G_GNUC_CONST; #define NM_TYPE_AP_SUPPORT (nm_ap_support_get_type ()) GType nm_opt_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_OPT_TYPE (nm_opt_type_get_type ()) -GType nm_vpn_manager_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_VPN_MANAGER_ERROR (nm_vpn_manager_error_get_type ()) -GType nm_dcb_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_DCB_ERROR (nm_dcb_error_get_type ()) GType nm_dispatcher_action_get_type (void) G_GNUC_CONST; #define NM_TYPE_DISPATCHER_ACTION (nm_dispatcher_action_get_type ()) +GType nm_auth_subject_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_AUTH_SUBJECT_TYPE (nm_auth_subject_type_get_type ()) GType nm_auth_call_result_get_type (void) G_GNUC_CONST; #define NM_TYPE_AUTH_CALL_RESULT (nm_auth_call_result_get_type ()) -GType nm_manager_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_MANAGER_ERROR (nm_manager_error_get_type ()) GType nm_rf_kill_state_get_type (void) G_GNUC_CONST; #define NM_TYPE_RF_KILL_STATE (nm_rf_kill_state_get_type ()) GType nm_rf_kill_type_get_type (void) G_GNUC_CONST; #define NM_TYPE_RF_KILL_TYPE (nm_rf_kill_type_get_type ()) -GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_SESSION_MONITOR_ERROR (nm_session_monitor_error_get_type ()) -GType nm_wimax_error_get_type (void) G_GNUC_CONST; -#define NM_TYPE_WIMAX_ERROR (nm_wimax_error_get_type ()) +GType nm_ip_config_source_get_type (void) G_GNUC_CONST; +#define NM_TYPE_IP_CONFIG_SOURCE (nm_ip_config_source_get_type ()) +GType nm_link_type_get_type (void) G_GNUC_CONST; +#define NM_TYPE_LINK_TYPE (nm_link_type_get_type ()) G_END_DECLS #endif /* __NM_ENUM_TYPES_H__ */ diff --git a/src/nm-firewall-manager.c b/src/nm-firewall-manager.c new file mode 100644 index 00000000..59520b3b --- /dev/null +++ b/src/nm-firewall-manager.c @@ -0,0 +1,440 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "nm-firewall-manager.h" +#include "nm-dbus-manager.h" +#include "nm-logging.h" + +#define NM_FIREWALL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_FIREWALL_MANAGER, \ + NMFirewallManagerPrivate)) + +G_DEFINE_TYPE (NMFirewallManager, nm_firewall_manager, G_TYPE_OBJECT) + +/* Properties */ +enum { + PROP_0 = 0, + PROP_AVAILABLE, + LAST_PROP +}; + +typedef struct { + NMDBusManager * dbus_mgr; + guint name_owner_id; + DBusGProxy * proxy; + gboolean running; + + GSList *pending_calls; +} NMFirewallManagerPrivate; + +enum { + STARTED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +/********************************************************************/ + +#define PENDING_CALL_DUMMY ((NMFirewallPendingCall) GUINT_TO_POINTER(1)) +#define PENDING_CALL_FROM_INFO(info) ((NMFirewallPendingCall) info) + +typedef struct { + NMFirewallManager *self; + char *iface; + FwAddToZoneFunc callback; + gpointer user_data; + guint id; + gboolean completed; + + guint idle_id; + DBusGProxyCall *dbus_call; +} CBInfo; + +static void +_cb_info_free (CBInfo *info) +{ + NMFirewallManagerPrivate *priv; + + g_return_if_fail (info != NULL); + + if (!info->completed) { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call cancelled [%u]", info->iface, info->id); + if (info->callback) { + GError *error; + + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Operation was cancelled"); + info->callback (error, info->user_data); + g_error_free (error); + } + } + g_free (info->iface); + + priv = NM_FIREWALL_MANAGER_GET_PRIVATE (info->self); + priv->pending_calls = g_slist_remove (priv->pending_calls, info); + g_object_unref (info->self); + + g_slice_free (CBInfo, info); +} + +static CBInfo * +_cb_info_create (NMFirewallManager *self, const char *iface, FwAddToZoneFunc callback, gpointer user_data) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + static guint id; + CBInfo *info; + + info = g_slice_new0 (CBInfo); + if (++id == 0) + ++id; + info->self = g_object_ref (self); + info->id = id; + info->iface = g_strdup (iface); + info->completed = FALSE; + info->callback = callback; + info->user_data = user_data; + + priv->pending_calls = g_slist_prepend (priv->pending_calls, info); + return info; +} + +static gboolean +add_or_change_idle_cb (gpointer user_data) +{ + CBInfo *info = user_data; + + if (info->idle_id == 0) { + /* operation was cancelled. _cb_info_free will invoke callback. */ + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone call pretends success [%u]", + info->iface, info->id); + if (info->callback) + info->callback (NULL, info->user_data); + info->completed = TRUE; + info->idle_id = 0; + } + + _cb_info_free (info); + return G_SOURCE_REMOVE; +} + +static void +add_or_change_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + CBInfo *info = user_data; + GError *error = NULL; + char *zone = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_STRING, &zone, + G_TYPE_INVALID)) { + g_assert (error); + if (g_strcmp0 (error->message, "ZONE_ALREADY_SET") != 0) { + nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", + info->iface, info->id, error->code, error->message); + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change failed [%u]: (%d) %s", + info->iface, info->id, error->code, error->message); + } + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change succeeded [%u]", + info->iface, info->id); + } + + if (info->callback) + info->callback (error, info->user_data); + + info->completed = TRUE; + g_free (zone); + g_clear_error (&error); +} + +NMFirewallPendingCall +nm_firewall_manager_add_or_change_zone (NMFirewallManager *self, + const char *iface, + const char *zone, + gboolean add, /* TRUE == add, FALSE == change */ + FwAddToZoneFunc callback, + gpointer user_data) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + CBInfo *info; + + if (priv->running == FALSE) { + if (callback) { + info = _cb_info_create (self, iface, callback, user_data); + info->idle_id = g_idle_add (add_or_change_idle_cb, info); + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u] (not running, simulate success)", iface, add ? "add" : "change", + zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id); + return PENDING_CALL_FROM_INFO (info); + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone add/change skipped (not running)", iface); + return PENDING_CALL_DUMMY; + } + } + + info = _cb_info_create (self, iface, callback, user_data); + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone %s -> %s%s%s [%u]", iface, add ? "add" : "change", + zone?"\"":"", zone ? zone : "default", zone?"\"":"", info->id); + info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + add ? "addInterface" : "changeZone", + add_or_change_cb, + info, + (GDestroyNotify) _cb_info_free, + 10000, /* timeout */ + G_TYPE_STRING, zone ? zone : "", + G_TYPE_STRING, iface, + G_TYPE_INVALID); + return PENDING_CALL_FROM_INFO (info); +} + +static void +remove_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + CBInfo *info = user_data; + GError *error = NULL; + char * zone = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_STRING, &zone, + G_TYPE_INVALID)) { + g_assert (error); + /* ignore UNKNOWN_INTERFACE errors */ + if (error->message && !strstr (error->message, "UNKNOWN_INTERFACE")) { + nm_log_warn (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", + info->iface, info->id, error->code, error->message); + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove failed [%u]: (%d) %s", + info->iface, info->id, error->code, error->message); + } + } else { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove succeeded [%u]", + info->iface, info->id); + } + + info->completed = TRUE; + g_free (zone); + g_clear_error (&error); +} + +NMFirewallPendingCall +nm_firewall_manager_remove_from_zone (NMFirewallManager *self, + const char *iface, + const char *zone) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + CBInfo *info; + + if (priv->running == FALSE) { + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove skipped (not running)", iface); + return PENDING_CALL_DUMMY; + } + + info = _cb_info_create (self, iface, NULL, NULL); + + nm_log_dbg (LOGD_FIREWALL, "(%s) firewall zone remove -> %s%s%s [%u]", iface, + zone?"\"":"", zone ? zone : "*", zone?"\"":"", info->id); + info->dbus_call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "removeInterface", + remove_cb, + info, + (GDestroyNotify) _cb_info_free, + 10000, /* timeout */ + G_TYPE_STRING, zone ? zone : "", + G_TYPE_STRING, iface, + G_TYPE_INVALID); + return PENDING_CALL_FROM_INFO (info); +} + +void nm_firewall_manager_cancel_call (NMFirewallManager *self, NMFirewallPendingCall call) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + GSList *pending; + CBInfo *info; + + g_return_if_fail (NM_IS_FIREWALL_MANAGER (self)); + + if (call == PENDING_CALL_DUMMY) + return; + + pending = g_slist_find (priv->pending_calls, call); + + if (!pending) + return; + priv->pending_calls = g_slist_remove_link (priv->pending_calls, pending); + + info = (CBInfo *) call; + if (info->idle_id) + info->idle_id = 0; + else { + dbus_g_proxy_cancel_call (NM_FIREWALL_MANAGER_GET_PRIVATE (self)->proxy, + info->dbus_call); + } +} + +static void +set_running (NMFirewallManager *self, gboolean now_running) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + gboolean old_running = priv->running; + + priv->running = now_running; + if (old_running != priv->running) + g_object_notify (G_OBJECT (self), NM_FIREWALL_MANAGER_AVAILABLE); +} + +static void +name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMFirewallManager *self = NM_FIREWALL_MANAGER (user_data); + gboolean old_owner_good = (old_owner && strlen (old_owner)); + gboolean new_owner_good = (new_owner && strlen (new_owner)); + + /* We only care about the firewall here */ + if (strcmp (FIREWALL_DBUS_SERVICE, name) != 0) + return; + + if (!old_owner_good && new_owner_good) { + nm_log_dbg (LOGD_FIREWALL, "firewall started"); + set_running (self, TRUE); + g_signal_emit (self, signals[STARTED], 0); + } else if (old_owner_good && !new_owner_good) { + nm_log_dbg (LOGD_FIREWALL, "firewall stopped"); + set_running (self, FALSE); + } +} + +/*******************************************************************/ + +NMFirewallManager * +nm_firewall_manager_get (void) +{ + static NMFirewallManager *singleton = NULL; + + if (G_UNLIKELY (!singleton)) { + singleton = NM_FIREWALL_MANAGER (g_object_new (NM_TYPE_FIREWALL_MANAGER, NULL)); + g_assert (singleton); + } + + return singleton; +} + +static void +nm_firewall_manager_init (NMFirewallManager * self) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self); + DBusGConnection *bus; + + priv->dbus_mgr = g_object_ref (nm_dbus_manager_get ()); + priv->name_owner_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed), + self); + priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, FIREWALL_DBUS_SERVICE); + nm_log_dbg (LOGD_FIREWALL, "firewall %s running", priv->running ? "is" : "is not" ); + + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (bus, + FIREWALL_DBUS_SERVICE, + FIREWALL_DBUS_PATH, + FIREWALL_DBUS_INTERFACE_ZONE); +} + +static void +set_property (GObject *object, guint prop_id, 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) +{ + switch (prop_id) { + case PROP_AVAILABLE: + g_value_set_boolean (value, NM_FIREWALL_MANAGER_GET_PRIVATE (object)->running); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (object); + + g_assert (priv->pending_calls == NULL); + + if (priv->dbus_mgr) { + g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); + priv->name_owner_id = 0; + g_clear_object (&priv->dbus_mgr); + } + + g_clear_object (&priv->proxy); + + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_firewall_manager_parent_class)->dispose (object); +} + +static void +nm_firewall_manager_class_init (NMFirewallManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMFirewallManagerPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + g_object_class_install_property + (object_class, PROP_AVAILABLE, + g_param_spec_boolean (NM_FIREWALL_MANAGER_AVAILABLE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + signals[STARTED] = + g_signal_new ("started", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMFirewallManagerClass, started), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + diff --git a/src/nm-firewall-manager.h b/src/nm-firewall-manager.h new file mode 100644 index 00000000..84cb5498 --- /dev/null +++ b/src/nm-firewall-manager.h @@ -0,0 +1,75 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_FIREWALL_MANAGER_H__ +#define __NETWORKMANAGER_FIREWALL_MANAGER_H__ + +#include + +#define FIREWALL_DBUS_SERVICE "org.fedoraproject.FirewallD1" +#define FIREWALL_DBUS_PATH "/org/fedoraproject/FirewallD1" +#define FIREWALL_DBUS_INTERFACE "org.fedoraproject.FirewallD1" +#define FIREWALL_DBUS_INTERFACE_ZONE "org.fedoraproject.FirewallD1.zone" + + +G_BEGIN_DECLS + +#define NM_TYPE_FIREWALL_MANAGER (nm_firewall_manager_get_type ()) +#define NM_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManager)) +#define NM_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) +#define NM_IS_FIREWALL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_FIREWALL_MANAGER)) +#define NM_IS_FIREWALL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FIREWALL_MANAGER)) +#define NM_FIREWALL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FIREWALL_MANAGER, NMFirewallManagerClass)) + +#define NM_FIREWALL_MANAGER_AVAILABLE "available" + +struct _NMFirewallPendingCall; +typedef struct _NMFirewallPendingCall *NMFirewallPendingCall; + +typedef struct { + GObject parent; +} NMFirewallManager; + +typedef struct { + GObjectClass parent; + + /* Signals */ + void (*started) (NMFirewallManager *manager); +} NMFirewallManagerClass; + +GType nm_firewall_manager_get_type (void); + +NMFirewallManager *nm_firewall_manager_get (void); + +typedef void (*FwAddToZoneFunc) (GError *error, gpointer user_data); + +NMFirewallPendingCall nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr, + const char *iface, + const char *zone, + gboolean add, + FwAddToZoneFunc callback, + gpointer user_data); +NMFirewallPendingCall nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr, + const char *iface, + const char *zone); + +void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, NMFirewallPendingCall fw_call); + +#endif /* __NETWORKMANAGER_FIREWALL_MANAGER_H__ */ diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c new file mode 100644 index 00000000..9d5cdc05 --- /dev/null +++ b/src/nm-iface-helper.c @@ -0,0 +1,538 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsystem-local-alloc.h" +#include "NetworkManagerUtils.h" +#include "nm-linux-platform.h" +#include "nm-dhcp-manager.h" +#include "nm-logging.h" +#include "main-utils.h" +#include "nm-rdisc.h" +#include "nm-lndp-rdisc.h" +#include "nm-utils.h" + +#if !defined(NM_DIST_VERSION) +# define NM_DIST_VERSION VERSION +#endif + +#define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid" + +static GMainLoop *main_loop = NULL; +static char *ifname = NULL; +static int ifindex = -1; +static gboolean slaac_required = FALSE; +static gboolean dhcp4_required = FALSE; +static int tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; +static guint32 priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4; +static guint32 priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6; + +static void +dhcp4_state_changed (NMDhcpClient *client, + NMDhcpState state, + NMIP4Config *ip4_config, + GHashTable *options, + gpointer user_data) +{ + static NMIP4Config *last_config = NULL; + NMIP4Config *existing; + + g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config)); + + nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d", ifname, state); + + switch (state) { + case NM_DHCP_STATE_BOUND: + g_assert (ip4_config); + existing = nm_ip4_config_capture (ifindex, FALSE); + if (last_config) + nm_ip4_config_subtract (existing, last_config); + + nm_ip4_config_merge (existing, ip4_config); + if (!nm_ip4_config_commit (existing, ifindex, priority_v4)) + nm_log_warn (LOGD_DHCP4, "(%s): failed to apply DHCPv4 config", ifname); + + if (last_config) { + g_object_unref (last_config); + last_config = nm_ip4_config_new (); + nm_ip4_config_replace (last_config, ip4_config, NULL); + } + break; + case NM_DHCP_STATE_TIMEOUT: + case NM_DHCP_STATE_DONE: + case NM_DHCP_STATE_FAIL: + if (dhcp4_required) { + nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed, quitting...", ifname); + g_main_loop_quit (main_loop); + } else + nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 timed out or failed", ifname); + break; + default: + break; + } +} + +static void +rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_data) +{ + static NMIP6Config *last_config = NULL; + NMIP6Config *existing; + NMIP6Config *ip6_config; + static int system_support = -1; + guint ifa_flags = 0x00; + int i; + + if (system_support == -1) { + /* + * Check, if both libnl and the kernel are recent enough, + * to help user space handling RA. If it's not supported, + * we have no ipv6-privacy and must add autoconf addresses + * as /128. The reason for the /128 is to prevent the kernel + * from adding a prefix route for this address. + **/ + system_support = nm_platform_check_support_libnl_extended_ifa_flags () && + nm_platform_check_support_kernel_extended_ifa_flags (); + } + + if (system_support) + ifa_flags = IFA_F_NOPREFIXROUTE; + if (tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR + || tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) + { + /* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */ + ifa_flags |= IFA_F_MANAGETEMPADDR; + } + + ip6_config = nm_ip6_config_new (); + + if (changed & NM_RDISC_CONFIG_GATEWAYS) { + /* Use the first gateway as ordered in router discovery cache. */ + if (rdisc->gateways->len) { + NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0); + + nm_ip6_config_set_gateway (ip6_config, &gateway->address); + } else + nm_ip6_config_set_gateway (ip6_config, NULL); + } + + if (changed & NM_RDISC_CONFIG_ADDRESSES) { + /* Rebuild address list from router discovery cache. */ + nm_ip6_config_reset_addresses (ip6_config); + + /* rdisc->addresses contains at most max_addresses entries. + * This is different from what the kernel does, which + * also counts static and temporary addresses when checking + * max_addresses. + **/ + for (i = 0; i < rdisc->addresses->len; i++) { + NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + NMPlatformIP6Address address; + + memset (&address, 0, sizeof (address)); + address.address = discovered_address->address; + address.plen = system_support ? 64 : 128; + address.timestamp = discovered_address->timestamp; + address.lifetime = discovered_address->lifetime; + address.preferred = discovered_address->preferred; + if (address.preferred > address.lifetime) + address.preferred = address.lifetime; + address.source = NM_IP_CONFIG_SOURCE_RDISC; + address.flags = ifa_flags; + + nm_ip6_config_add_address (ip6_config, &address); + } + } + + if (changed & NM_RDISC_CONFIG_ROUTES) { + /* Rebuild route list from router discovery cache. */ + nm_ip6_config_reset_routes (ip6_config); + + for (i = 0; i < rdisc->routes->len; i++) { + NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i); + NMPlatformIP6Route route; + + /* Only accept non-default routes. The router has no idea what the + * local configuration or user preferences are, so sending routes + * with a prefix length of 0 is quite rude and thus ignored. + */ + if (discovered_route->plen > 0) { + memset (&route, 0, sizeof (route)); + route.network = discovered_route->network; + route.plen = discovered_route->plen; + route.gateway = discovered_route->gateway; + route.source = NM_IP_CONFIG_SOURCE_RDISC; + route.metric = priority_v6; + + nm_ip6_config_add_route (ip6_config, &route); + } + } + } + + if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { + /* Unsupported until systemd DHCPv6 is ready */ + } + + /* hop_limit == 0 is a special value "unspecified", so do not touch + * in this case */ + if (changed & NM_RDISC_CONFIG_HOP_LIMIT && rdisc->hop_limit > 0) { + char val[16]; + + g_snprintf (val, sizeof (val), "%d", rdisc->hop_limit); + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "hop_limit"), val); + } + + if (changed & NM_RDISC_CONFIG_MTU) { + char val[16]; + + g_snprintf (val, sizeof (val), "%d", rdisc->mtu); + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "mtu"), val); + } + + existing = nm_ip6_config_capture (ifindex, FALSE, tempaddr); + if (last_config) + nm_ip6_config_subtract (existing, last_config); + + nm_ip6_config_merge (existing, ip6_config); + if (!nm_ip6_config_commit (existing, ifindex)) + nm_log_warn (LOGD_IP6, "(%s): failed to apply IPv6 config", ifname); + + if (last_config) { + g_object_unref (last_config); + last_config = nm_ip6_config_new (); + nm_ip6_config_replace (last_config, ip6_config, NULL); + } +} + +static void +rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data) +{ + if (slaac_required) { + nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed, quitting...", ifname); + g_main_loop_quit (main_loop); + } else + nm_log_warn (LOGD_IP6, "(%s): IPv6 timed out or failed", ifname); +} + +static gboolean +quit_handler (gpointer user_data) +{ + gboolean *quit_early_ptr = user_data; + + *quit_early_ptr = TRUE; + g_main_loop_quit (main_loop); + return G_SOURCE_CONTINUE; +} + +static void +setup_signals (gboolean *quit_early_ptr) +{ + sigset_t sigmask; + + sigemptyset (&sigmask); + pthread_sigmask (SIG_SETMASK, &sigmask, NULL); + + signal (SIGPIPE, SIG_IGN); + g_unix_signal_add (SIGINT, quit_handler, quit_early_ptr); + g_unix_signal_add (SIGTERM, quit_handler, quit_early_ptr); +} + +int +main (int argc, char *argv[]) +{ + char *opt_log_level = NULL; + char *opt_log_domains = NULL; + gboolean debug = FALSE, g_fatal_warnings = FALSE, become_daemon = FALSE; + gboolean show_version = FALSE, slaac = FALSE; + char *bad_domains = NULL, *dhcp4_hostname = NULL, *uuid = NULL; + char *iid_str = NULL, *dhcp4_clientid = NULL, *dhcp4_address = NULL; + gs_unref_object NMDhcpManager *dhcp_mgr = NULL; + GError *error = NULL; + gboolean wrote_pidfile = FALSE; + gs_free char *pidfile = NULL; + gboolean quit_early = FALSE; + gs_unref_object NMDhcpClient *dhcp4_client = NULL; + gs_unref_object NMRDisc *rdisc = NULL; + GByteArray *hwaddr = NULL; + size_t hwaddr_len = 0; + gconstpointer tmp; + gs_free NMUtilsIPv6IfaceId *iid = NULL; + gint64 priority64_v4 = -1; + gint64 priority64_v6 = -1; + + GOptionEntry options[] = { + /* Interface/IP config */ + { "ifname", 'i', 0, G_OPTION_ARG_STRING, &ifname, N_("The interface to manage"), N_("eth0") }, + { "uuid", 'u', 0, G_OPTION_ARG_STRING, &uuid, N_("Connection UUID"), N_("661e8cd0-b618-46b8-9dc9-31a52baaa16b") }, + { "slaac", 's', 0, G_OPTION_ARG_NONE, &slaac, N_("Whether to manage IPv6 SLAAC"), NULL }, + { "slaac-required", '6', 0, G_OPTION_ARG_NONE, &slaac_required, N_("Whether SLAAC must be successful"), NULL }, + { "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &tempaddr, N_("Use an IPv6 temporary privacy address"), NULL }, + { "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &dhcp4_address, N_("Current DHCPv4 address"), NULL }, + { "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL }, + { "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL }, + { "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") }, + { "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") }, + { "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") }, + { "iid", 'e', 0, G_OPTION_ARG_STRING, &iid_str, N_("Hex-encoded Interface Identifier"), N_("") }, + + /* Logging/debugging */ + { "version", 'V', 0, G_OPTION_ARG_NONE, &show_version, N_("Print NetworkManager version and exit"), NULL }, + { "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &become_daemon, N_("Don't become a daemon"), NULL }, + { "debug", 'b', 0, G_OPTION_ARG_NONE, &debug, N_("Don't become a daemon, and log to stderr"), NULL }, + { "log-level", 0, 0, G_OPTION_ARG_STRING, &opt_log_level, N_("Log level: one of [%s]"), "INFO" }, + { "log-domains", 0, 0, G_OPTION_ARG_STRING, &opt_log_domains, + N_("Log domains separated by ',': any combination of [%s]"), + "PLATFORM,RFKILL,WIFI" }, + { "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, N_("Make all warnings fatal"), NULL }, + {NULL} + }; + + setpgid (getpid (), getpid ()); + + if (!nm_main_utils_early_setup ("nm-iface-helper", + &argv, + &argc, + options, + NULL, + _("nm-iface-helper is a small, standalone process that manages a single network interface."))) + exit (1); + + if (show_version) { + fprintf (stdout, NM_DIST_VERSION "\n"); + exit (0); + } + + if (!ifname || !uuid) { + fprintf (stderr, _("An interface name and UUID are required\n")); + exit (1); + } + + if (!nm_logging_setup (opt_log_level, + opt_log_domains, + &bad_domains, + &error)) { + fprintf (stderr, + _("%s. Please use --help to see a list of valid options.\n"), + error->message); + exit (1); + } else if (bad_domains) { + fprintf (stderr, + _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"), + bad_domains); + g_clear_pointer (&bad_domains, g_free); + } + + pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, ifindex); + g_assert (pidfile); + + /* check pid file */ + if (nm_main_utils_check_pidfile (pidfile, "nm-iface-helper")) + exit (1); + + if (become_daemon && !debug) { + if (daemon (0, 0) < 0) { + int saved_errno; + + saved_errno = errno; + fprintf (stderr, _("Could not daemonize: %s [error %u]\n"), + g_strerror (saved_errno), + saved_errno); + exit (1); + } + if (nm_main_utils_write_pidfile (pidfile)) + wrote_pidfile = TRUE; + } + + /* Set up unix signal handling - before creating threads, but after daemonizing! */ + main_loop = g_main_loop_new (NULL, FALSE); + setup_signals (&quit_early); + + if (g_fatal_warnings) { + GLogLevelFlags fatal_mask; + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; + g_log_set_always_fatal (fatal_mask); + } + + nm_logging_syslog_openlog (debug); + +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + nm_log_info (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting..."); + + /* Set up platform interaction layer */ + nm_linux_platform_setup (); + + ifindex = nm_platform_link_get_ifindex (ifname); + if (ifindex <= 0) { + fprintf (stderr, _("Failed to find interface index for %s\n"), ifname); + exit (1); + } + + tmp = nm_platform_link_get_address (ifindex, &hwaddr_len); + if (tmp) { + hwaddr = g_byte_array_sized_new (hwaddr_len); + g_byte_array_append (hwaddr, tmp, hwaddr_len); + } + + if (iid_str) { + GBytes *bytes; + gsize ignored = 0; + + bytes = nm_utils_hexstr2bin (iid_str); + if (!bytes || g_bytes_get_size (bytes) != sizeof (*iid)) { + fprintf (stderr, _("(%s): Invalid IID %s\n"), ifname, iid_str); + exit (1); + } + iid = g_bytes_unref_to_data (bytes, &ignored); + } + + if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32) + priority_v4 = (guint32) priority64_v4; + + if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32) + priority_v6 = (guint32) priority64_v6; + + if (dhcp4_address) { + nm_platform_sysctl_set (nm_utils_ip4_property_path (ifname, "promote_secondaries"), "1"); + + /* Initialize DHCP manager */ + dhcp_mgr = nm_dhcp_manager_get (); + g_assert (dhcp_mgr != NULL); + + dhcp4_client = nm_dhcp_manager_start_ip4 (dhcp_mgr, + ifname, + ifindex, + hwaddr, + uuid, + priority_v4, + !!dhcp4_hostname, + dhcp4_hostname, + dhcp4_clientid, + 45, + NULL, + dhcp4_address); + g_assert (dhcp4_client); + g_signal_connect (dhcp4_client, + NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, + G_CALLBACK (dhcp4_state_changed), + NULL); + } + + if (slaac) { + nm_platform_link_set_user_ipv6ll_enabled (ifindex, TRUE); + + rdisc = nm_lndp_rdisc_new (ifindex, ifname); + g_assert (rdisc); + + if (iid) + nm_rdisc_set_iid (rdisc, *iid); + + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra"), "1"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_defrtr"), "0"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_pinfo"), "0"); + nm_platform_sysctl_set (nm_utils_ip6_property_path (ifname, "accept_ra_rtr_pref"), "0"); + + g_signal_connect (rdisc, + NM_RDISC_CONFIG_CHANGED, + G_CALLBACK (rdisc_config_changed), + NULL); + g_signal_connect (rdisc, + NM_RDISC_RA_TIMEOUT, + G_CALLBACK (rdisc_ra_timeout), + NULL); + nm_rdisc_start (rdisc); + } + + if (!quit_early) + g_main_loop_run (main_loop); + + g_clear_pointer (&hwaddr, g_byte_array_unref); + + nm_logging_syslog_closelog (); + + if (pidfile && wrote_pidfile) + unlink (pidfile); + + nm_log_info (LOGD_CORE, "exiting"); + exit (0); +} + +/*******************************************************/ +/* Stub functions */ + +gconstpointer nm_config_get (void); +const char *nm_config_get_dhcp_client (gpointer unused); +gboolean nm_config_get_configure_and_quit (gpointer unused); +gconstpointer nm_dbus_manager_get (void); +void nm_dbus_manager_register_exported_type (gpointer unused, GType gtype, gconstpointer unused2); +void nm_dbus_manager_register_object (gpointer unused, const char *path, gpointer object); + +gconstpointer +nm_config_get (void) +{ + return GUINT_TO_POINTER (1); +} + +const char * +nm_config_get_dhcp_client (gpointer unused) +{ + return "internal"; +} + +gboolean +nm_config_get_configure_and_quit (gpointer unused) +{ + return TRUE; +} + +gconstpointer +nm_dbus_manager_get (void) +{ + return GUINT_TO_POINTER (1); +} + +void +nm_dbus_manager_register_exported_type (gpointer unused, GType gtype, gconstpointer unused2) +{ +} + +void +nm_dbus_manager_register_object (gpointer unused, const char *path, gpointer object) +{ +} + diff --git a/src/nm-ip4-config-glue.h b/src/nm-ip4-config-glue.h index 738dff92..9488be9b 100644 --- a/src/nm-ip4-config-glue.h +++ b/src/nm-ip4-config-glue.h @@ -68,6 +68,6 @@ const DBusGObjectInfo dbus_glib_nm_ip4_config_object_info = { 1, 0, "\0", "org.freedesktop.NetworkManager.IP4Config\0PropertiesChanged\0\0", -"org.freedesktop.NetworkManager.IP4Config\0Gateway\0gateway\0read\0org.freedesktop.NetworkManager.IP4Config\0Addresses\0addresses\0read\0org.freedesktop.NetworkManager.IP4Config\0Routes\0routes\0read\0org.freedesktop.NetworkManager.IP4Config\0Nameservers\0nameservers\0read\0org.freedesktop.NetworkManager.IP4Config\0Domains\0domains\0read\0org.freedesktop.NetworkManager.IP4Config\0Searches\0searches\0read\0org.freedesktop.NetworkManager.IP4Config\0WinsServers\0wins_servers\0read\0\0" +"org.freedesktop.NetworkManager.IP4Config\0Addresses\0addresses\0read\0org.freedesktop.NetworkManager.IP4Config\0AddressData\0address_data\0read\0org.freedesktop.NetworkManager.IP4Config\0Gateway\0gateway\0read\0org.freedesktop.NetworkManager.IP4Config\0Routes\0routes\0read\0org.freedesktop.NetworkManager.IP4Config\0RouteData\0route_data\0read\0org.freedesktop.NetworkManager.IP4Config\0Nameservers\0nameservers\0read\0org.freedesktop.NetworkManager.IP4Config\0Domains\0domains\0read\0org.freedesktop.NetworkManager.IP4Config\0Searches\0searches\0read\0org.freedesktop.NetworkManager.IP4Config\0WinsServers\0wins_servers\0read\0\0" }; diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index e27c0436..fd466780 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -19,18 +19,20 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include +#include #include "nm-ip4-config.h" -#include "libgsystem.h" -#include "nm-platform.h" #include "nm-utils.h" +#include "nm-platform.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" #include "nm-ip4-config-glue.h" #include "NetworkManagerUtils.h" -#include "nm-utils-private.h" +#include "nm-core-internal.h" G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT) @@ -51,6 +53,7 @@ typedef struct { char *nis_domain; GArray *wins; guint32 mtu; + NMIPConfigSource mtu_source; } NMIP4ConfigPrivate; /* internal guint32 are assigned to gobject properties of type uint. Ensure, that uint is large enough */ @@ -59,9 +62,11 @@ G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF); enum { PROP_0, - PROP_GATEWAY, + PROP_ADDRESS_DATA, PROP_ADDRESSES, + PROP_ROUTE_DATA, PROP_ROUTES, + PROP_GATEWAY, PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, @@ -176,7 +181,7 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) NMIP4Config *config; NMIP4ConfigPrivate *priv; guint i; - guint lowest_metric = G_MAXUINT; + guint32 lowest_metric = G_MAXUINT32; guint32 old_gateway = 0; gboolean has_gateway = FALSE; @@ -191,14 +196,14 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) g_array_unref (priv->routes); priv->addresses = nm_platform_ip4_address_get_all (ifindex); - priv->routes = nm_platform_ip4_route_get_all (ifindex, TRUE); + priv->routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); /* Extract gateway from default route */ old_gateway = priv->gateway; for (i = 0; i < priv->routes->len; i++) { const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i); - if (route->network == 0) { + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { if (route->metric < lowest_metric) { priv->gateway = route->gateway; lowest_metric = route->metric; @@ -235,6 +240,8 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) } /* actually, nobody should be connected to the signal, just to be sure, notify */ + _NOTIFY (config, PROP_ADDRESS_DATA); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ADDRESSES); _NOTIFY (config, PROP_ROUTES); if (priv->gateway != old_gateway) @@ -244,42 +251,36 @@ nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) } gboolean -nm_ip4_config_commit (const NMIP4Config *config, int ifindex) +nm_ip4_config_commit (const NMIP4Config *config, int ifindex, guint32 default_route_metric) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - int mtu = nm_ip4_config_get_mtu (config); + guint32 mtu = nm_ip4_config_get_mtu (config); int i; g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (config != NULL, FALSE); /* Addresses */ - nm_platform_ip4_address_sync (ifindex, priv->addresses); + nm_platform_ip4_address_sync (ifindex, priv->addresses, default_route_metric); /* Routes */ { int count = nm_ip4_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count); - NMPlatformIP4Route route; + const NMPlatformIP4Route *route; gboolean success; for (i = 0; i < count; i++) { - memcpy (&route, nm_ip4_config_get_route (config, i), sizeof (route)); + route = nm_ip4_config_get_route (config, i); /* Don't add the route if it's more specific than one of the subnets * the device already has an IP address on. */ - if ( route.gateway == 0 - && nm_ip4_config_destination_is_direct (config, route.network, route.plen)) + if ( route->gateway == 0 + && nm_ip4_config_destination_is_direct (config, route->network, route->plen)) continue; - /* Don't add the default route if the connection - * is never supposed to be the default connection. - */ - if (nm_ip4_config_get_never_default (config) && route.network == 0) - continue; - - g_array_append_val (routes, route); + g_array_append_vals (routes, route, 1); } success = nm_platform_ip4_route_sync (ifindex, routes); @@ -296,7 +297,7 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex) } void -nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, int default_route_metric) +nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric) { guint naddresses, nroutes, nnameservers, nsearches; int i; @@ -304,74 +305,83 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, i if (!setting) return; + g_return_if_fail (NM_IS_SETTING_IP4_CONFIG (setting)); + g_object_freeze_notify (G_OBJECT (config)); - naddresses = nm_setting_ip4_config_get_num_addresses (setting); - nroutes = nm_setting_ip4_config_get_num_routes (setting); - nnameservers = nm_setting_ip4_config_get_num_dns (setting); - nsearches = nm_setting_ip4_config_get_num_dns_searches (setting); + naddresses = nm_setting_ip_config_get_num_addresses (setting); + nroutes = nm_setting_ip_config_get_num_routes (setting); + nnameservers = nm_setting_ip_config_get_num_dns (setting); + nsearches = nm_setting_ip_config_get_num_dns_searches (setting); /* Gateway */ - if (nm_setting_ip4_config_get_never_default (setting)) + if (nm_setting_ip_config_get_never_default (setting)) nm_ip4_config_set_never_default (config, TRUE); - else if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) + else if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip4_config_set_never_default (config, FALSE); - for (i = 0; i < naddresses; i++) { - guint32 gateway = nm_ip4_address_get_gateway (nm_setting_ip4_config_get_address (setting, i)); + if (nm_setting_ip_config_get_gateway (setting)) { + guint32 gateway; - if (gateway) { - nm_ip4_config_set_gateway (config, gateway); - break; - } + inet_pton (AF_INET, nm_setting_ip_config_get_gateway (setting), &gateway); + nm_ip4_config_set_gateway (config, gateway); } /* Addresses */ for (i = 0; i < naddresses; i++) { - NMIP4Address *s_addr = nm_setting_ip4_config_get_address (setting, i); - const char *label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (setting, i)); + NMIPAddress *s_addr = nm_setting_ip_config_get_address (setting, i); + GVariant *label; NMPlatformIP4Address address; memset (&address, 0, sizeof (address)); - address.address = nm_ip4_address_get_address (s_addr); - address.plen = nm_ip4_address_get_prefix (s_addr); + nm_ip_address_get_address_binary (s_addr, &address.address); + address.plen = nm_ip_address_get_prefix (s_addr); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; - address.source = NM_PLATFORM_SOURCE_USER; + address.source = NM_IP_CONFIG_SOURCE_USER; + + label = nm_ip_address_get_attribute (s_addr, "label"); if (label) - g_strlcpy (address.label, label, sizeof (address.label)); + g_strlcpy (address.label, g_variant_get_string (label, NULL), sizeof (address.label)); nm_ip4_config_add_address (config, &address); } /* Routes */ - if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) + if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip4_config_reset_routes (config); for (i = 0; i < nroutes; i++) { - NMIP4Route *s_route = nm_setting_ip4_config_get_route (setting, i); + NMIPRoute *s_route = nm_setting_ip_config_get_route (setting, i); NMPlatformIP4Route route; memset (&route, 0, sizeof (route)); - route.network = nm_ip4_route_get_dest (s_route); - route.plen = nm_ip4_route_get_prefix (s_route); - route.gateway = nm_ip4_route_get_next_hop (s_route); - route.metric = nm_ip4_route_get_metric (s_route); - if (!route.metric) + nm_ip_route_get_dest_binary (s_route, &route.network); + route.plen = nm_ip_route_get_prefix (s_route); + nm_ip_route_get_next_hop_binary (s_route, &route.gateway); + if (nm_ip_route_get_metric (s_route) == -1) route.metric = default_route_metric; - route.source = NM_PLATFORM_SOURCE_USER; + else + route.metric = nm_ip_route_get_metric (s_route); + route.source = NM_IP_CONFIG_SOURCE_USER; + + g_assert (route.plen > 0); nm_ip4_config_add_route (config, &route); } /* DNS */ - if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) { + if (nm_setting_ip_config_get_ignore_auto_dns (setting)) { nm_ip4_config_reset_nameservers (config); nm_ip4_config_reset_domains (config); nm_ip4_config_reset_searches (config); } - for (i = 0; i < nnameservers; i++) - nm_ip4_config_add_nameserver (config, nm_setting_ip4_config_get_dns (setting, i)); + for (i = 0; i < nnameservers; i++) { + guint32 ip; + + if (inet_pton (AF_INET, nm_setting_ip_config_get_dns (setting, i), &ip) == 1) + nm_ip4_config_add_nameserver (config, ip); + } for (i = 0; i < nsearches; i++) - nm_ip4_config_add_search (config, nm_setting_ip4_config_get_dns_search (setting, i)); + nm_ip4_config_add_search (config, nm_setting_ip_config_get_dns_search (setting, i)); g_object_thaw_notify (G_OBJECT (config)); } @@ -379,17 +389,17 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, i NMSetting * nm_ip4_config_create_setting (const NMIP4Config *config) { - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; guint32 gateway; guint naddresses, nroutes, nnameservers, nsearches; const char *method = NULL; int i; - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); if (!config) { g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); return NM_SETTING (s_ip4); } @@ -403,7 +413,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) /* Addresses */ for (i = 0; i < naddresses; i++) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); - NMIP4Address *s_addr; + NMIPAddress *s_addr; /* Detect dynamic address */ if (address->lifetime != NM_PLATFORM_LIFETIME_PERMANENT) { @@ -415,61 +425,58 @@ nm_ip4_config_create_setting (const NMIP4Config *config) if (!method) method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - s_addr = nm_ip4_address_new (); + s_addr = nm_ip_address_new_binary (AF_INET, &address->address, address->plen, NULL); + if (*address->label) + nm_ip_address_set_attribute (s_addr, "label", g_variant_new_string (address->label)); - nm_ip4_address_set_address (s_addr, address->address); - nm_ip4_address_set_prefix (s_addr, address->plen); - /* For backwards compatibility, attach the gateway to an address if it's - * in the same subnet. - */ - if (same_prefix (address->address, gateway, address->plen)) - nm_ip4_address_set_gateway (s_addr, gateway); + nm_setting_ip_config_add_address (s_ip4, s_addr); + nm_ip_address_unref (s_addr); + } - if (*address->label) - NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, s_addr, address->label)); - else - nm_setting_ip4_config_add_address (s_ip4, s_addr); - nm_ip4_address_unref (s_addr); + /* Gateway */ + if ( gateway + && nm_setting_ip_config_get_num_addresses (s_ip4) > 0) { + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet4_ntop (gateway, NULL), + NULL); } /* Use 'disabled' if the method wasn't previously set */ if (!method) method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, method, NULL); /* Routes */ for (i = 0; i < nroutes; i++) { const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i); - NMIP4Route *s_route; + NMIPRoute *s_route; /* Ignore default route. */ if (!route->plen) continue; /* Ignore routes provided by external sources */ - if (route->source != NM_PLATFORM_SOURCE_USER) + if (route->source != NM_IP_CONFIG_SOURCE_USER) continue; - s_route = nm_ip4_route_new (); - nm_ip4_route_set_dest (s_route, route->network); - nm_ip4_route_set_prefix (s_route, route->plen); - nm_ip4_route_set_next_hop (s_route, route->gateway); - nm_ip4_route_set_metric (s_route, route->metric); - - nm_setting_ip4_config_add_route (s_ip4, s_route); - nm_ip4_route_unref (s_route); + s_route = nm_ip_route_new_binary (AF_INET, + &route->network, route->plen, + &route->gateway, route->metric, + NULL); + nm_setting_ip_config_add_route (s_ip4, s_route); + nm_ip_route_unref (s_route); } /* DNS */ for (i = 0; i < nnameservers; i++) { guint32 nameserver = nm_ip4_config_get_nameserver (config, i); - nm_setting_ip4_config_add_dns (s_ip4, nameserver); + nm_setting_ip_config_add_dns (s_ip4, nm_utils_inet4_ntop (nameserver, NULL)); } for (i = 0; i < nsearches; i++) { const char *search = nm_ip4_config_get_search (config, i); - nm_setting_ip4_config_add_dns_search (s_ip4, search); + nm_setting_ip_config_add_dns_search (s_ip4, search); } return NM_SETTING (s_ip4); @@ -517,7 +524,8 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src) /* MTU */ if (!nm_ip4_config_get_mtu (dst)) - nm_ip4_config_set_mtu (dst, nm_ip4_config_get_mtu (src)); + nm_ip4_config_set_mtu (dst, nm_ip4_config_get_mtu (src), + nm_ip4_config_get_mtu_source (src)); /* NIS */ for (i = 0; i < nm_ip4_config_get_num_nis_servers (src); i++) @@ -583,6 +591,9 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src) if (nm_ip4_config_get_gateway (src) == nm_ip4_config_get_gateway (dst)) nm_ip4_config_set_gateway (dst, 0); + if (!nm_ip4_config_get_num_addresses (dst)) + nm_ip4_config_set_gateway (dst, 0); + /* routes */ for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) { const NMPlatformIP4Route *src_route = nm_ip4_config_get_route (src, i); @@ -631,7 +642,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src) /* MTU */ if (nm_ip4_config_get_mtu (src) == nm_ip4_config_get_mtu (dst)) - nm_ip4_config_set_mtu (dst, 0); + nm_ip4_config_set_mtu (dst, 0, NM_IP_CONFIG_SOURCE_UNKNOWN); /* NIS */ for (i = 0; i < nm_ip4_config_get_num_nis_servers (src); i++) { @@ -871,7 +882,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev /* mtu */ if (src_priv->mtu != dst_priv->mtu) { - nm_ip4_config_set_mtu (dst, src_priv->mtu); + nm_ip4_config_set_mtu (dst, src_priv->mtu, src_priv->mtu_source); has_minor_changes = TRUE; } @@ -927,8 +938,8 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail) for (i = 0; i < nm_ip4_config_get_num_searches (config); i++) g_message (" search: %s", nm_ip4_config_get_search (config, i)); - g_message (" mss: %u", nm_ip4_config_get_mss (config)); - g_message (" mtu: %u", nm_ip4_config_get_mtu (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)); /* NIS */ for (i = 0; i < nm_ip4_config_get_num_nis_servers (config); i++) { @@ -936,7 +947,7 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail) g_message (" nis: %s", nm_utils_inet4_ntop (tmp, NULL)); } - g_message (" nisdmn: %s", nm_ip4_config_get_nis_domain (config)); + g_message (" nisdmn: %s", str_if_set (nm_ip4_config_get_nis_domain (config), "(none)")); /* WINS */ for (i = 0; i < nm_ip4_config_get_num_wins (config); i++) { @@ -1009,6 +1020,7 @@ nm_ip4_config_reset_addresses (NMIP4Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } } @@ -1052,7 +1064,7 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) * 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_PLATFORM_SOURCE_KERNEL && new->source != item_old.source) + if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.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; @@ -1066,6 +1078,7 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } @@ -1077,6 +1090,7 @@ nm_ip4_config_del_address (NMIP4Config *config, guint i) g_return_if_fail (i < priv->addresses->len); g_array_remove_index (priv->addresses, i); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } @@ -1121,6 +1135,7 @@ nm_ip4_config_reset_routes (NMIP4Config *config) if (priv->routes->len != 0) { g_array_set_size (priv->routes, 0); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } } @@ -1139,10 +1154,11 @@ void nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - NMPlatformSource old_source; + NMIPConfigSource old_source; int i; g_return_if_fail (new != NULL); + g_return_if_fail (new->plen > 0); for (i = 0; i < priv->routes->len; i++ ) { NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i); @@ -1160,6 +1176,7 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new) g_array_append_val (priv->routes, *new); NOTIFY: + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1171,6 +1188,7 @@ nm_ip4_config_del_route (NMIP4Config *config, guint i) g_return_if_fail (i < priv->routes->len); g_array_remove_index (priv->routes, i); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1190,6 +1208,58 @@ nm_ip4_config_get_route (const NMIP4Config *config, guint i) return &g_array_index (priv->routes, NMPlatformIP4Route, i); } +const NMPlatformIP4Route * +nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + guint i; + NMPlatformIP4Route *best_route = NULL; + + g_return_val_if_fail (host, NULL); + + for (i = 0; i < priv->routes->len; i++) { + NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i); + + if (item->gateway != 0) + continue; + + if (best_route && best_route->plen > item->plen) + continue; + + if (nm_utils_ip4_address_clear_host_address (host, item->plen) != nm_utils_ip4_address_clear_host_address (item->network, item->plen)) + continue; + + if (best_route && best_route->metric <= item->metric) + continue; + + best_route = item; + } + + return best_route; +} + +const NMPlatformIP4Address * +nm_ip4_config_get_subnet_for_host (const NMIP4Config *config, guint32 host) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + guint i; + NMPlatformIP4Address *subnet = NULL; + + g_return_val_if_fail (host, NULL); + + for (i = 0; i < priv->addresses->len; i++) { + NMPlatformIP4Address *item = &g_array_index (priv->addresses, NMPlatformIP4Address, i); + + if (subnet && subnet->plen >= item->plen) + continue; + if (nm_utils_ip4_address_clear_host_address (host, item->plen) != nm_utils_ip4_address_clear_host_address (item->address, item->plen)) + continue; + subnet = item; + } + + return subnet; +} + /******************************************************************/ void @@ -1503,11 +1573,15 @@ nm_ip4_config_get_wins (const NMIP4Config *config, guint i) /******************************************************************/ void -nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu) +nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu, NMIPConfigSource source) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - priv->mtu = mtu; + if (source > priv->mtu_source) { + priv->mtu = mtu; + priv->mtu_source = source; + } else if (source == priv->mtu_source && (!priv->mtu || priv->mtu > mtu)) + priv->mtu = mtu; } guint32 @@ -1518,6 +1592,14 @@ nm_ip4_config_get_mtu (const NMIP4Config *config) return priv->mtu; } +NMIPConfigSource +nm_ip4_config_get_mtu_source (const NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + + return priv->mtu_source; +} + /******************************************************************/ static inline void @@ -1651,6 +1733,15 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object); } +static void +gvalue_destroy (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -1659,11 +1750,41 @@ get_property (GObject *object, guint prop_id, NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); switch (prop_id) { - case PROP_GATEWAY: - if (priv->gateway) - g_value_set_string (value, nm_utils_inet4_ntop (priv->gateway, NULL)); - else - g_value_set_string (value, NULL); + case PROP_ADDRESS_DATA: + { + GPtrArray *addresses = g_ptr_array_new (); + int naddr = nm_ip4_config_get_num_addresses (config); + int i; + + for (i = 0; i < naddr; i++) { + const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); + GHashTable *addr_hash; + GValue *val; + + addr_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet4_ntop (address->address, NULL)); + g_hash_table_insert (addr_hash, "address", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, address->plen); + g_hash_table_insert (addr_hash, "prefix", val); + + if (*address->label) { + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, address->label); + g_hash_table_insert (addr_hash, "label", val); + } + + g_ptr_array_add (addresses, addr_hash); + } + + g_value_take_boxed (value, addresses); + } break; case PROP_ADDRESSES: { @@ -1674,10 +1795,11 @@ get_property (GObject *object, guint prop_id, for (i = 0; i < naddr; i++) { const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); + guint32 gateway = i == 0 ? priv->gateway : 0; g_array_append_val (array, address->address); g_array_append_val (array, address->plen); - g_array_append_val (array, priv->gateway); + g_array_append_val (array, gateway); g_ptr_array_add (addresses, array); } @@ -1685,6 +1807,47 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, addresses); } break; + case PROP_ROUTE_DATA: + { + GPtrArray *routes = g_ptr_array_new (); + guint nroutes = nm_ip4_config_get_num_routes (config); + int i; + + for (i = 0; i < nroutes; i++) { + const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i); + GHashTable *route_hash; + GValue *val; + + route_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet4_ntop (route->network, NULL)); + g_hash_table_insert (route_hash, "dest", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->plen); + g_hash_table_insert (route_hash, "prefix", val); + + if (route->gateway) { + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet4_ntop (route->gateway, NULL)); + g_hash_table_insert (route_hash, "next-hop", val); + } + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->metric); + g_hash_table_insert (route_hash, "metric", val); + + g_ptr_array_add (routes, route_hash); + } + + g_value_take_boxed (value, routes); + } + break; case PROP_ROUTES: { GPtrArray *routes = g_ptr_array_new (); @@ -1693,8 +1856,14 @@ get_property (GObject *object, guint prop_id, for (i = 0; i < nroutes; i++) { const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i); - GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4); + GArray *array; + + /* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the + * plen is positive. Skip the default routes not to break older clients. */ + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) + continue; + array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4); g_array_append_val (array, route->network); g_array_append_val (array, route->plen); g_array_append_val (array, route->gateway); @@ -1706,6 +1875,12 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, routes); } break; + case PROP_GATEWAY: + if (priv->gateway) + g_value_set_string (value, nm_utils_inet4_ntop (priv->gateway, NULL)); + else + g_value_set_string (value, NULL); + break; case PROP_NAMESERVERS: g_value_set_boxed (value, priv->nameservers); break; @@ -1734,48 +1909,51 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) object_class->get_property = get_property; object_class->finalize = finalize; - obj_properties[PROP_GATEWAY] = - g_param_spec_string (NM_IP4_CONFIG_GATEWAY, - "Gateway", - "IP4 gateway", - NULL, - G_PARAM_READABLE); + obj_properties[PROP_ADDRESS_DATA] = + g_param_spec_boxed (NM_IP4_CONFIG_ADDRESS_DATA, "", "", + DBUS_TYPE_NM_IP_ADDRESSES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESSES] = - g_param_spec_boxed (NM_IP4_CONFIG_ADDRESSES, - "Addresses", - "IP4 addresses", - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_PARAM_READABLE); + g_param_spec_boxed (NM_IP4_CONFIG_ADDRESSES, "", "", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_DATA] = + g_param_spec_boxed (NM_IP4_CONFIG_ROUTE_DATA, "", "", + DBUS_TYPE_NM_IP_ROUTES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTES] = - g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, - "Routes", - "Routes", - DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_PARAM_READABLE); + g_param_spec_boxed (NM_IP4_CONFIG_ROUTES, "", "", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_GATEWAY] = + g_param_spec_string (NM_IP4_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = - g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, - "Nameservers", - "DNS list", + g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DOMAINS] = - g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, - "Domains", - "Domains", + g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_SEARCHES] = - g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, - "Searches", - "Searches", + g_param_spec_boxed (NM_IP4_CONFIG_SEARCHES, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_WINS_SERVERS] = - g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, - "WinsServers", - "WINS server list", + g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, "", "", DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, obj_properties); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index c9096bb3..5ac455d8 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -18,12 +18,12 @@ * Copyright (C) 2008–2013 Red Hat, Inc. */ -#ifndef NM_IP4_CONFIG_H -#define NM_IP4_CONFIG_H +#ifndef __NETWORKMANAGER_IP4_CONFIG_H__ +#define __NETWORKMANAGER_IP4_CONFIG_H__ #include -#include "nm-platform.h" +#include "nm-types.h" #include "nm-setting-ip4-config.h" #define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ()) @@ -33,22 +33,26 @@ #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)) -typedef struct { +struct _NMIP4Config { GObject parent; -} NMIP4Config; +}; typedef struct { GObjectClass parent; } NMIP4ConfigClass; +#define NM_IP4_CONFIG_ADDRESS_DATA "address-data" +#define NM_IP4_CONFIG_ROUTE_DATA "route-data" #define NM_IP4_CONFIG_GATEWAY "gateway" -#define NM_IP4_CONFIG_ADDRESSES "addresses" -#define NM_IP4_CONFIG_ROUTES "routes" #define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_SEARCHES "searches" #define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" +/* deprecated */ +#define NM_IP4_CONFIG_ADDRESSES "addresses" +#define NM_IP4_CONFIG_ROUTES "routes" + GType nm_ip4_config_get_type (void); @@ -60,8 +64,8 @@ const char * nm_ip4_config_get_dbus_path (const NMIP4Config *config); /* Integration with nm-platform and nm-setting */ NMIP4Config *nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf); -gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex); -void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting, int default_route_metric); +gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, guint32 default_route_metric); +void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric); NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config); /* Utility functions */ @@ -92,6 +96,9 @@ void nm_ip4_config_del_route (NMIP4Config *config, guint i); guint32 nm_ip4_config_get_num_routes (const NMIP4Config *config); const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint32 i); +const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host); +const NMPlatformIP4Address *nm_ip4_config_get_subnet_for_host (const NMIP4Config *config, guint32 host); + /* Nameservers */ void nm_ip4_config_reset_nameservers (NMIP4Config *config); void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver); @@ -134,8 +141,9 @@ guint32 nm_ip4_config_get_num_wins (const NMIP4Config *config); guint32 nm_ip4_config_get_wins (const NMIP4Config *config, guint i); /* MTU */ -void nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu); +void nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu, NMIPConfigSource source); guint32 nm_ip4_config_get_mtu (const NMIP4Config *config); +NMIPConfigSource nm_ip4_config_get_mtu_source (const NMIP4Config *config); void nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only); gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b); @@ -146,4 +154,4 @@ gboolean nm_ip4_config_equal (const NMIP4Config *a, const NMIP4Config *b); gboolean nm_ip4_config_capture_resolv_conf (GArray *nameservers, const char *rc_contents); -#endif /* NM_IP4_CONFIG_H */ +#endif /* __NETWORKMANAGER_IP4_CONFIG_H__ */ diff --git a/src/nm-ip6-config-glue.h b/src/nm-ip6-config-glue.h index 62fbe1c5..87836ebb 100644 --- a/src/nm-ip6-config-glue.h +++ b/src/nm-ip6-config-glue.h @@ -68,6 +68,6 @@ const DBusGObjectInfo dbus_glib_nm_ip6_config_object_info = { 1, 0, "\0", "org.freedesktop.NetworkManager.IP6Config\0PropertiesChanged\0\0", -"org.freedesktop.NetworkManager.IP6Config\0Gateway\0gateway\0read\0org.freedesktop.NetworkManager.IP6Config\0Addresses\0addresses\0read\0org.freedesktop.NetworkManager.IP6Config\0Routes\0routes\0read\0org.freedesktop.NetworkManager.IP6Config\0Nameservers\0nameservers\0read\0org.freedesktop.NetworkManager.IP6Config\0Domains\0domains\0read\0org.freedesktop.NetworkManager.IP6Config\0Searches\0searches\0read\0\0" +"org.freedesktop.NetworkManager.IP6Config\0Addresses\0addresses\0read\0org.freedesktop.NetworkManager.IP6Config\0AddressData\0address_data\0read\0org.freedesktop.NetworkManager.IP6Config\0Gateway\0gateway\0read\0org.freedesktop.NetworkManager.IP6Config\0Routes\0routes\0read\0org.freedesktop.NetworkManager.IP6Config\0RouteData\0route_data\0read\0org.freedesktop.NetworkManager.IP6Config\0Nameservers\0nameservers\0read\0org.freedesktop.NetworkManager.IP6Config\0Domains\0domains\0read\0org.freedesktop.NetworkManager.IP6Config\0Searches\0searches\0read\0\0" }; diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index aaf5e701..db64e726 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -19,14 +19,16 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include +#include #include "nm-ip6-config.h" #include "nm-glib-compat.h" -#include "libgsystem.h" -#include "nm-platform.h" #include "nm-utils.h" +#include "nm-platform.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" #include "nm-ip6-config-glue.h" @@ -52,9 +54,11 @@ typedef struct { enum { PROP_0, - PROP_GATEWAY, + PROP_ADDRESS_DATA, PROP_ADDRESSES, + PROP_ROUTE_DATA, PROP_ROUTES, + PROP_GATEWAY, PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, @@ -169,7 +173,9 @@ static gboolean routes_are_duplicate (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gboolean consider_gateway_and_metric) { return IN6_ARE_ADDR_EQUAL (&a->network, &b->network) && a->plen == b->plen && - (!consider_gateway_and_metric || (IN6_ARE_ADDR_EQUAL (&a->gateway, &b->gateway) && a->metric == b->metric)); + ( !consider_gateway_and_metric + || ( IN6_ARE_ADDR_EQUAL (&a->gateway, &b->gateway) + && nm_utils_ip6_route_metric_normalize (a->metric) == nm_utils_ip6_route_metric_normalize (b->metric))); } static gint @@ -272,6 +278,7 @@ nm_ip6_config_addresses_sort (NMIP6Config *self, NMSettingIP6ConfigPrivacy use_t g_free (data_pre); if (changed) { + _NOTIFY (self, PROP_ADDRESS_DATA); _NOTIFY (self, PROP_ADDRESSES); return TRUE; } @@ -285,7 +292,7 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co NMIP6Config *config; NMIP6ConfigPrivate *priv; guint i; - guint lowest_metric = G_MAXUINT; + guint32 lowest_metric = G_MAXUINT32; struct in6_addr old_gateway = IN6ADDR_ANY_INIT; gboolean has_gateway = FALSE; gboolean notify_nameservers = FALSE; @@ -301,14 +308,14 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co g_array_unref (priv->routes); priv->addresses = nm_platform_ip6_address_get_all (ifindex); - priv->routes = nm_platform_ip6_route_get_all (ifindex, TRUE); + priv->routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); /* Extract gateway from default route */ old_gateway = priv->gateway; for (i = 0; i < priv->routes->len; i++) { const NMPlatformIP6Route *route = &g_array_index (priv->routes, NMPlatformIP6Route, i); - if (IN6_IS_ADDR_UNSPECIFIED (&route->network)) { + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { if (route->metric < lowest_metric) { priv->gateway = route->gateway; lowest_metric = route->metric; @@ -347,7 +354,9 @@ nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6Co /* actually, nobody should be connected to the signal, just to be sure, notify */ if (notify_nameservers) _NOTIFY (config, PROP_NAMESERVERS); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); if (!IN6_ARE_ADDR_EQUAL (&priv->gateway, &old_gateway)) _NOTIFY (config, PROP_GATEWAY); @@ -372,25 +381,19 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex) { int count = nm_ip6_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count); - NMPlatformIP6Route route; + const NMPlatformIP6Route *route; for (i = 0; i < count; i++) { - memcpy (&route, nm_ip6_config_get_route (config, i), sizeof (route)); + route = nm_ip6_config_get_route (config, i); /* Don't add the route if it's more specific than one of the subnets * the device already has an IP address on. */ - if ( IN6_IS_ADDR_UNSPECIFIED (&route.gateway) - && nm_ip6_config_destination_is_direct (config, &route.network, route.plen)) + if ( IN6_IS_ADDR_UNSPECIFIED (&route->gateway) + && nm_ip6_config_destination_is_direct (config, &route->network, route->plen)) continue; - /* Don't add the default route if the connection - * is never supposed to be the default connection. - */ - if (nm_ip6_config_get_never_default (config) && IN6_IS_ADDR_UNSPECIFIED (&route.network)) - continue; - - g_array_append_val (routes, route); + g_array_append_vals (routes, route, 1); } success = nm_platform_ip6_route_sync (ifindex, routes); @@ -401,79 +404,88 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex) } void -nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting, int default_route_metric) +nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric) { guint naddresses, nroutes, nnameservers, nsearches; + const char *gateway_str; int i; if (!setting) return; - naddresses = nm_setting_ip6_config_get_num_addresses (setting); - nroutes = nm_setting_ip6_config_get_num_routes (setting); - nnameservers = nm_setting_ip6_config_get_num_dns (setting); - nsearches = nm_setting_ip6_config_get_num_dns_searches (setting); + g_return_if_fail (NM_IS_SETTING_IP6_CONFIG (setting)); + + naddresses = nm_setting_ip_config_get_num_addresses (setting); + nroutes = nm_setting_ip_config_get_num_routes (setting); + nnameservers = nm_setting_ip_config_get_num_dns (setting); + nsearches = nm_setting_ip_config_get_num_dns_searches (setting); g_object_freeze_notify (G_OBJECT (config)); /* Gateway */ - if (nm_setting_ip6_config_get_never_default (setting)) + if (nm_setting_ip_config_get_never_default (setting)) nm_ip6_config_set_never_default (config, TRUE); - else if (nm_setting_ip6_config_get_ignore_auto_routes (setting)) + else if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip6_config_set_never_default (config, FALSE); - for (i = 0; i < naddresses; i++) { - const struct in6_addr *gateway = nm_ip6_address_get_gateway (nm_setting_ip6_config_get_address (setting, i)); + gateway_str = nm_setting_ip_config_get_gateway (setting); + if (gateway_str) { + struct in6_addr gateway; - if (gateway && !IN6_IS_ADDR_UNSPECIFIED (gateway)) { - nm_ip6_config_set_gateway (config, gateway); - break; - } + inet_pton (AF_INET6, gateway_str, &gateway); + nm_ip6_config_set_gateway (config, &gateway); } /* Addresses */ for (i = 0; i < naddresses; i++) { - NMIP6Address *s_addr = nm_setting_ip6_config_get_address (setting, i); + NMIPAddress *s_addr = nm_setting_ip_config_get_address (setting, i); NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); - address.address = *nm_ip6_address_get_address (s_addr); - address.plen = nm_ip6_address_get_prefix (s_addr); + nm_ip_address_get_address_binary (s_addr, &address.address); + address.plen = nm_ip_address_get_prefix (s_addr); address.lifetime = NM_PLATFORM_LIFETIME_PERMANENT; address.preferred = NM_PLATFORM_LIFETIME_PERMANENT; - address.source = NM_PLATFORM_SOURCE_USER; + address.source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (config, &address); } /* Routes */ - if (nm_setting_ip6_config_get_ignore_auto_routes (setting)) + if (nm_setting_ip_config_get_ignore_auto_routes (setting)) nm_ip6_config_reset_routes (config); for (i = 0; i < nroutes; i++) { - NMIP6Route *s_route = nm_setting_ip6_config_get_route (setting, i); + NMIPRoute *s_route = nm_setting_ip_config_get_route (setting, i); NMPlatformIP6Route route; memset (&route, 0, sizeof (route)); - route.network = *nm_ip6_route_get_dest (s_route); - route.plen = nm_ip6_route_get_prefix (s_route); - route.gateway = *nm_ip6_route_get_next_hop (s_route); - route.metric = nm_ip6_route_get_metric (s_route); - if (!route.metric) + nm_ip_route_get_dest_binary (s_route, &route.network); + route.plen = nm_ip_route_get_prefix (s_route); + nm_ip_route_get_next_hop_binary (s_route, &route.gateway); + if (nm_ip_route_get_metric (s_route) == -1) route.metric = default_route_metric; - route.source = NM_PLATFORM_SOURCE_USER; + else + route.metric = nm_ip_route_get_metric (s_route); + route.source = NM_IP_CONFIG_SOURCE_USER; + + g_assert (route.plen > 0); nm_ip6_config_add_route (config, &route); } /* DNS */ - if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) { + if (nm_setting_ip_config_get_ignore_auto_dns (setting)) { nm_ip6_config_reset_nameservers (config); nm_ip6_config_reset_domains (config); nm_ip6_config_reset_searches (config); } - for (i = 0; i < nnameservers; i++) - nm_ip6_config_add_nameserver (config, nm_setting_ip6_config_get_dns (setting, i)); + for (i = 0; i < nnameservers; i++) { + struct in6_addr ip; + + if (inet_pton (AF_INET6, nm_setting_ip_config_get_dns (setting, i), &ip) == 1) + nm_ip6_config_add_nameserver (config, &ip); + } for (i = 0; i < nsearches; i++) - nm_ip6_config_add_search (config, nm_setting_ip6_config_get_dns_search (setting, i)); + nm_ip6_config_add_search (config, nm_setting_ip_config_get_dns_search (setting, i)); g_object_thaw_notify (G_OBJECT (config)); } @@ -481,17 +493,17 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting, i NMSetting * nm_ip6_config_create_setting (const NMIP6Config *config) { - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; const struct in6_addr *gateway; guint naddresses, nroutes, nnameservers, nsearches; const char *method = NULL; int i; - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); if (!config) { g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); return NM_SETTING (s_ip6); } @@ -505,7 +517,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) /* Addresses */ for (i = 0; i < naddresses; i++) { const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); - NMIP6Address *s_addr; + NMIPAddress *s_addr; /* Ignore link-local address. */ if (IN6_IS_ADDR_LINKLOCAL (&address->address)) { @@ -524,26 +536,28 @@ nm_ip6_config_create_setting (const NMIP6Config *config) if (!method || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - s_addr = nm_ip6_address_new (); - - nm_ip6_address_set_address (s_addr, &address->address); - nm_ip6_address_set_prefix (s_addr, address->plen); - if (gateway) - nm_ip6_address_set_gateway (s_addr, gateway); + s_addr = nm_ip_address_new_binary (AF_INET6, &address->address, address->plen, NULL); + nm_setting_ip_config_add_address (s_ip6, s_addr); + nm_ip_address_unref (s_addr); + } - nm_setting_ip6_config_add_address (s_ip6, s_addr); - nm_ip6_address_unref (s_addr); + /* Gateway */ + if ( gateway + && nm_setting_ip_config_get_num_addresses (s_ip6) > 0) { + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet6_ntop (gateway, NULL), + NULL); } /* Use 'ignore' if the method wasn't previously set */ if (!method) method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, method, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, method, NULL); /* Routes */ for (i = 0; i < nroutes; i++) { const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); - NMIP6Route *s_route; + NMIPRoute *s_route; /* Ignore link-local route. */ if (IN6_IS_ADDR_LINKLOCAL (&route->network)) @@ -554,30 +568,27 @@ nm_ip6_config_create_setting (const NMIP6Config *config) continue; /* Ignore routes provided by external sources */ - if (route->source != NM_PLATFORM_SOURCE_USER) + if (route->source != NM_IP_CONFIG_SOURCE_USER) continue; - s_route = nm_ip6_route_new (); - nm_ip6_route_set_dest (s_route, &route->network); - nm_ip6_route_set_prefix (s_route, route->plen); - if (!IN6_IS_ADDR_UNSPECIFIED (&route->network)) - nm_ip6_route_set_next_hop (s_route, &route->gateway); - nm_ip6_route_set_metric (s_route, route->metric); - - nm_setting_ip6_config_add_route (s_ip6, s_route); - nm_ip6_route_unref (s_route); + s_route = nm_ip_route_new_binary (AF_INET6, + &route->network, route->plen, + &route->gateway, route->metric, + NULL); + nm_setting_ip_config_add_route (s_ip6, s_route); + nm_ip_route_unref (s_route); } /* DNS */ for (i = 0; i < nnameservers; i++) { const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (config, i); - nm_setting_ip6_config_add_dns (s_ip6, nameserver); + nm_setting_ip_config_add_dns (s_ip6, nm_utils_inet6_ntop (nameserver, NULL)); } for (i = 0; i < nsearches; i++) { const char *search = nm_ip6_config_get_search (config, i); - nm_setting_ip6_config_add_dns_search (s_ip6, search); + nm_setting_ip_config_add_dns_search (s_ip6, search); } return NM_SETTING (s_ip6); @@ -694,6 +705,9 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) if (src_tmp && dst_tmp && IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp)) nm_ip6_config_set_gateway (dst, NULL); + if (!nm_ip6_config_get_num_addresses (dst)) + nm_ip6_config_set_gateway (dst, NULL); + /* routes */ for (i = 0; i < nm_ip6_config_get_num_routes (src); i++) { const NMPlatformIP6Route *src_route = nm_ip6_config_get_route (src, i); @@ -956,7 +970,7 @@ nm_ip6_config_dump (const NMIP6Config *config, const char *detail) for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) g_message (" search: %s", nm_ip6_config_get_search (config, i)); - g_message (" mss: %u", nm_ip6_config_get_mss (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)); } @@ -1012,6 +1026,7 @@ nm_ip6_config_reset_addresses (NMIP6Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } } @@ -1055,7 +1070,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) * 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_PLATFORM_SOURCE_KERNEL && new->source != item_old.source) + if ( (new->source == NM_IP_CONFIG_SOURCE_KERNEL && new->source != item_old.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; @@ -1069,6 +1084,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } @@ -1080,6 +1096,7 @@ nm_ip6_config_del_address (NMIP6Config *config, guint i) g_return_if_fail (i < priv->addresses->len); g_array_remove_index (priv->addresses, i); + _NOTIFY (config, PROP_ADDRESS_DATA); _NOTIFY (config, PROP_ADDRESSES); } @@ -1125,6 +1142,7 @@ nm_ip6_config_reset_routes (NMIP6Config *config) if (priv->routes->len != 0) { g_array_set_size (priv->routes, 0); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } } @@ -1143,10 +1161,11 @@ void nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); - NMPlatformSource old_source; + NMIPConfigSource old_source; int i; g_return_if_fail (new != NULL); + g_return_if_fail (new->plen > 0); for (i = 0; i < priv->routes->len; i++ ) { NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i); @@ -1164,6 +1183,7 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new) g_array_append_val (priv->routes, *new); NOTIFY: + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1175,6 +1195,7 @@ nm_ip6_config_del_route (NMIP6Config *config, guint i) g_return_if_fail (i < priv->routes->len); g_array_remove_index (priv->routes, i); + _NOTIFY (config, PROP_ROUTE_DATA); _NOTIFY (config, PROP_ROUTES); } @@ -1194,6 +1215,68 @@ nm_ip6_config_get_route (const NMIP6Config *config, guint i) return &g_array_index (priv->routes, NMPlatformIP6Route, 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); + guint i; + struct in6_addr network2, host2; + NMPlatformIP6Route *best_route = NULL; + + g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL); + + for (i = 0; i < priv->routes->len; i++) { + NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i); + + if (!IN6_IS_ADDR_UNSPECIFIED (&item->gateway)) + continue; + + if (best_route && best_route->plen > item->plen) + continue; + + nm_utils_ip6_address_clear_host_address (&host2, host, item->plen); + nm_utils_ip6_address_clear_host_address (&network2, &item->network, item->plen); + + if (!IN6_ARE_ADDR_EQUAL (&network2, &host2)) + continue; + + if (best_route && + nm_utils_ip6_route_metric_normalize (best_route->metric) <= nm_utils_ip6_route_metric_normalize (item->metric)) + continue; + + best_route = item; + } + + return best_route; +} + +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); + guint i; + NMPlatformIP6Address *subnet = NULL; + struct in6_addr subnet2, host2; + + g_return_val_if_fail (host && !IN6_IS_ADDR_UNSPECIFIED (host), NULL); + + for (i = 0; i < priv->addresses->len; i++) { + NMPlatformIP6Address *item = &g_array_index (priv->addresses, NMPlatformIP6Address, i); + + if (subnet && subnet->plen >= item->plen) + continue; + + nm_utils_ip6_address_clear_host_address (&host2, host, item->plen); + nm_utils_ip6_address_clear_host_address (&subnet2, &item->address, item->plen); + + if (IN6_ARE_ADDR_EQUAL (&subnet2, &host2)) + subnet = item; + } + + return subnet; +} + + /******************************************************************/ void @@ -1531,6 +1614,15 @@ nameservers_to_gvalue (GArray *array, GValue *value) g_value_take_boxed (value, dns); } +static void +gvalue_destroy (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -1539,11 +1631,34 @@ get_property (GObject *object, guint prop_id, NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object); switch (prop_id) { - case PROP_GATEWAY: - if (!IN6_IS_ADDR_UNSPECIFIED (&priv->gateway)) - g_value_set_string (value, nm_utils_inet6_ntop (&priv->gateway, NULL)); - else - g_value_set_string (value, NULL); + case PROP_ADDRESS_DATA: + { + GPtrArray *addresses = g_ptr_array_new (); + int naddr = nm_ip6_config_get_num_addresses (config); + int i; + + for (i = 0; i < naddr; i++) { + const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); + GHashTable *addr_hash; + GValue *val; + + addr_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&address->address, NULL)); + g_hash_table_insert (addr_hash, "address", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, address->plen); + g_hash_table_insert (addr_hash, "prefix", val); + + g_ptr_array_add (addresses, addr_hash); + } + + g_value_take_boxed (value, addresses); + } break; case PROP_ADDRESSES: { @@ -1576,7 +1691,7 @@ get_property (GObject *object, guint prop_id, /* Gateway */ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) (gateway ? gateway : &in6addr_any), sizeof (*gateway)); + g_byte_array_append (ba, (guint8 *) (i == 0 && gateway ? gateway : &in6addr_any), sizeof (*gateway)); g_value_take_boxed (&element, ba); g_value_array_append (array, &element); g_value_unset (&element); @@ -1587,6 +1702,47 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, addresses); } break; + case PROP_ROUTE_DATA: + { + GPtrArray *routes = g_ptr_array_new (); + guint nroutes = nm_ip6_config_get_num_routes (config); + int i; + + for (i = 0; i < nroutes; i++) { + const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); + GHashTable *route_hash; + GValue *val; + + route_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&route->network, NULL)); + g_hash_table_insert (route_hash, "dest", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->plen); + g_hash_table_insert (route_hash, "prefix", val); + + if (!IN6_IS_ADDR_UNSPECIFIED (&route->gateway)) { + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, nm_utils_inet6_ntop (&route->gateway, NULL)); + g_hash_table_insert (route_hash, "next-hop", val); + } + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, route->metric); + g_hash_table_insert (route_hash, "metric", val); + + g_ptr_array_add (routes, route_hash); + } + + g_value_take_boxed (value, routes); + } + break; case PROP_ROUTES: { GPtrArray *routes = g_ptr_array_new (); @@ -1594,12 +1750,18 @@ get_property (GObject *object, guint prop_id, int i; for (i = 0; i < nroutes; i++) { + GValueArray *array; const NMPlatformIP6Route *route = nm_ip6_config_get_route (config, i); - - GValueArray *array = g_value_array_new (4); GByteArray *ba; GValue element = G_VALUE_INIT; + /* legacy versions of nm_ip6_route_set_prefix() in libnm-util assert that the + * plen is positive. Skip the default routes not to break older clients. */ + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) + continue; + + array = g_value_array_new (4); + g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); ba = g_byte_array_new (); g_byte_array_append (ba, (guint8 *) &route->network, sizeof (route->network)); @@ -1630,6 +1792,12 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, routes); } break; + case PROP_GATEWAY: + if (!IN6_IS_ADDR_UNSPECIFIED (&priv->gateway)) + g_value_set_string (value, nm_utils_inet6_ntop (&priv->gateway, NULL)); + else + g_value_set_string (value, NULL); + break; case PROP_NAMESERVERS: nameservers_to_gvalue (priv->nameservers, value); break; @@ -1657,42 +1825,46 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) object_class->finalize = finalize; /* properties */ - obj_properties[PROP_GATEWAY] = - g_param_spec_string (NM_IP6_CONFIG_GATEWAY, - "Gateway", - "IP6 Gateway", - NULL, - G_PARAM_READABLE); + obj_properties[PROP_ADDRESS_DATA] = + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESS_DATA, "", "", + DBUS_TYPE_NM_IP_ADDRESSES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDRESSES] = - g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, - "Addresses", - "IP6 addresses", - DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - G_PARAM_READABLE); + g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, "", "", + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_DATA] = + g_param_spec_boxed (NM_IP6_CONFIG_ROUTE_DATA, "", "", + DBUS_TYPE_NM_IP_ROUTES, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTES] = - g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, - "Routes", - "Routes", + g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, "", "", DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_GATEWAY] = + g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = - g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, - "Nameservers", - "DNS list", + g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, "", "", DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_DOMAINS] = - g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, - "Domains", - "Domains", + g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_SEARCHES] = - g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, - "Searches", - "Searches", + g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "", DBUS_TYPE_G_ARRAY_OF_STRING, - G_PARAM_READABLE); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, obj_properties); diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index b7b9d83e..f1d2dc8d 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -18,12 +18,13 @@ * Copyright (C) 2008–2013 Red Hat, Inc. */ -#ifndef NM_IP6_CONFIG_H -#define NM_IP6_CONFIG_H +#ifndef __NETWORKMANAGER_IP6_CONFIG_H__ +#define __NETWORKMANAGER_IP6_CONFIG_H__ #include +#include -#include "nm-platform.h" +#include "nm-types.h" #include "nm-setting-ip6-config.h" #define NM_TYPE_IP6_CONFIG (nm_ip6_config_get_type ()) @@ -33,21 +34,25 @@ #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)) -typedef struct { +struct _NMIP6Config { GObject parent; -} NMIP6Config; +}; typedef struct { GObjectClass parent; } NMIP6ConfigClass; +#define NM_IP6_CONFIG_ADDRESS_DATA "address-data" +#define NM_IP6_CONFIG_ROUTE_DATA "route-data" #define NM_IP6_CONFIG_GATEWAY "gateway" -#define NM_IP6_CONFIG_ADDRESSES "addresses" -#define NM_IP6_CONFIG_ROUTES "routes" #define NM_IP6_CONFIG_NAMESERVERS "nameservers" #define NM_IP6_CONFIG_DOMAINS "domains" #define NM_IP6_CONFIG_SEARCHES "searches" +/* deprecated */ +#define NM_IP6_CONFIG_ADDRESSES "addresses" +#define NM_IP6_CONFIG_ROUTES "routes" + GType nm_ip6_config_get_type (void); @@ -60,7 +65,7 @@ const char * nm_ip6_config_get_dbus_path (const NMIP6Config *config); /* Integration with nm-platform and nm-setting */ NMIP6Config *nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary); gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex); -void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting, int default_route_metric); +void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric); NMSetting *nm_ip6_config_create_setting (const NMIP6Config *config); /* Utility functions */ @@ -93,6 +98,9 @@ void nm_ip6_config_del_route (NMIP6Config *config, guint i); guint32 nm_ip6_config_get_num_routes (const NMIP6Config *config); const NMPlatformIP6Route *nm_ip6_config_get_route (const NMIP6Config *config, guint32 i); +const NMPlatformIP6Route *nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host); +const NMPlatformIP6Address *nm_ip6_config_get_subnet_for_host (const NMIP6Config *config, const struct in6_addr *host); + /* Nameservers */ void nm_ip6_config_reset_nameservers (NMIP6Config *config); void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *nameserver); @@ -127,4 +135,4 @@ gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b); gboolean nm_ip6_config_capture_resolv_conf (GArray *nameservers, const char *rc_contents); -#endif /* NM_IP6_CONFIG_H */ +#endif /* __NETWORKMANAGER_IP6_CONFIG_H__ */ diff --git a/src/nm-logging.c b/src/nm-logging.c new file mode 100644 index 00000000..f1291fa7 --- /dev/null +++ b/src/nm-logging.c @@ -0,0 +1,487 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "nm-glib-compat.h" +#include "nm-logging.h" +#include "nm-errors.h" + +static void +nm_log_handler (const gchar *log_domain, + GLogLevelFlags level, + const gchar *message, + gpointer ignored); + +static NMLogLevel log_level = LOGL_INFO; +static char *log_domains; +static NMLogDomain logging[LOGL_MAX]; +static gboolean logging_set_up; +static gboolean syslog_opened; +static char *logging_domains_to_string; + +typedef struct { + NMLogDomain num; + const char *name; +} LogDesc; + +static const char *level_names[LOGL_MAX] = { + [LOGL_TRACE] = "TRACE", + [LOGL_DEBUG] = "DEBUG", + [LOGL_INFO] = "INFO", + [LOGL_WARN] = "WARN", + [LOGL_ERR] = "ERR", +}; + +static const LogDesc domain_descs[] = { + { LOGD_NONE, "NONE" }, + { LOGD_PLATFORM, "PLATFORM" }, + { LOGD_RFKILL, "RFKILL" }, + { LOGD_ETHER, "ETHER" }, + { LOGD_WIFI, "WIFI" }, + { LOGD_BT, "BT" }, + { LOGD_MB, "MB" }, + { LOGD_DHCP4, "DHCP4" }, + { LOGD_DHCP6, "DHCP6" }, + { LOGD_PPP, "PPP" }, + { LOGD_WIFI_SCAN, "WIFI_SCAN" }, + { LOGD_IP4, "IP4" }, + { LOGD_IP6, "IP6" }, + { LOGD_AUTOIP4, "AUTOIP4" }, + { LOGD_DNS, "DNS" }, + { LOGD_VPN, "VPN" }, + { LOGD_SHARING, "SHARING" }, + { LOGD_SUPPLICANT,"SUPPLICANT" }, + { LOGD_AGENTS, "AGENTS" }, + { LOGD_SETTINGS, "SETTINGS" }, + { LOGD_SUSPEND, "SUSPEND" }, + { LOGD_CORE, "CORE" }, + { LOGD_DEVICE, "DEVICE" }, + { LOGD_OLPC, "OLPC" }, + { LOGD_WIMAX, "WIMAX" }, + { LOGD_INFINIBAND,"INFINIBAND" }, + { LOGD_FIREWALL, "FIREWALL" }, + { LOGD_ADSL, "ADSL" }, + { LOGD_BOND, "BOND" }, + { LOGD_VLAN, "VLAN" }, + { LOGD_BRIDGE, "BRIDGE" }, + { LOGD_DBUS_PROPS,"DBUS_PROPS" }, + { LOGD_TEAM, "TEAM" }, + { LOGD_CONCHECK, "CONCHECK" }, + { LOGD_DCB, "DCB" }, + { LOGD_DISPATCH, "DISPATCH" }, + { 0, NULL } +}; + +/* Combined domains */ +#define LOGD_ALL_STRING "ALL" +#define LOGD_DEFAULT_STRING "DEFAULT" +#define LOGD_DHCP_STRING "DHCP" +#define LOGD_IP_STRING "IP" + +/************************************************************************/ + +static void +_ensure_initialized (void) +{ + if (G_UNLIKELY (!logging_set_up)) + nm_logging_setup ("INFO", "DEFAULT", NULL, NULL); +} + +static gboolean +match_log_level (const char *level, + NMLogLevel *out_level, + GError **error) +{ + int i; + + for (i = 0; i < LOGL_MAX; i++) { + if (!g_ascii_strcasecmp (level_names[i], level)) { + *out_level = i; + return TRUE; + } + } + + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_LOG_LEVEL, + _("Unknown log level '%s'"), level); + return FALSE; +} + +gboolean +nm_logging_setup (const char *level, + const char *domains, + char **bad_domains, + GError **error) +{ + GString *unrecognized = NULL; + NMLogDomain new_logging[LOGL_MAX]; + NMLogLevel new_log_level = log_level; + char **tmp, **iter; + int i; + + g_return_val_if_fail (!bad_domains || !*bad_domains, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + logging_set_up = TRUE; + + for (i = 0; i < LOGL_MAX; i++) + new_logging[i] = 0; + + /* levels */ + if (level && *level) { + if (!match_log_level (level, &new_log_level, error)) + return FALSE; + } + + /* domains */ + if (!domains || !*domains) + domains = log_domains ? log_domains : "DEFAULT"; + + tmp = g_strsplit_set (domains, ", ", 0); + for (iter = tmp; iter && *iter; iter++) { + const LogDesc *diter; + NMLogLevel domain_log_level; + NMLogDomain bits; + char *p; + + if (!strlen (*iter)) + continue; + + p = strchr (*iter, ':'); + if (p) { + *p = '\0'; + if (!match_log_level (p + 1, &domain_log_level, error)) { + g_strfreev (tmp); + return FALSE; + } + } else + domain_log_level = new_log_level; + + bits = 0; + + /* Check for combined domains */ + if (!g_ascii_strcasecmp (*iter, LOGD_ALL_STRING)) + bits = LOGD_ALL; + else if (!g_ascii_strcasecmp (*iter, LOGD_DEFAULT_STRING)) + bits = LOGD_DEFAULT; + else if (!g_ascii_strcasecmp (*iter, LOGD_DHCP_STRING)) + bits = LOGD_DHCP; + else if (!g_ascii_strcasecmp (*iter, LOGD_IP_STRING)) + bits = LOGD_IP; + + /* Check for compatibility domains */ + else if (!g_ascii_strcasecmp (*iter, "HW")) + bits = LOGD_PLATFORM; + + else { + for (diter = &domain_descs[0]; diter->name; diter++) { + if (!g_ascii_strcasecmp (diter->name, *iter)) { + bits = diter->num; + break; + } + } + } + + if (!bits) { + if (!bad_domains) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_LOG_DOMAIN, + _("Unknown log domain '%s'"), *iter); + return FALSE; + } + + if (unrecognized) + g_string_append (unrecognized, ", "); + else + unrecognized = g_string_new (NULL); + g_string_append (unrecognized, *iter); + continue; + } + + for (i = 0; i < domain_log_level; i++) + new_logging[i] &= ~bits; + for (i = domain_log_level; i < LOGL_MAX; i++) + new_logging[i] |= bits; + } + g_strfreev (tmp); + + if (log_domains != (char *)domains) { + g_free (log_domains); + log_domains = g_strdup (domains); + } + + g_clear_pointer (&logging_domains_to_string, g_free); + + log_level = new_log_level; + for (i = 0; i < LOGL_MAX; i++) + logging[i] = new_logging[i]; + + if (unrecognized) + *bad_domains = g_string_free (unrecognized, FALSE); + + return TRUE; +} + +const char * +nm_logging_level_to_string (void) +{ + return level_names[log_level]; +} + +const char * +nm_logging_all_levels_to_string (void) +{ + static GString *str; + + if (G_UNLIKELY (!str)) { + int i; + + str = g_string_new (NULL); + for (i = 0; i < LOGL_MAX; i++) { + if (str->len) + g_string_append_c (str, ','); + g_string_append (str, level_names[i]); + } + } + + return str->str; +} + +const char * +nm_logging_domains_to_string (void) +{ + _ensure_initialized (); + + if (G_UNLIKELY (!logging_domains_to_string)) { + const LogDesc *diter; + GString *str; + int i; + + /* We don't just return g_strdup (log_domains) because we want to expand + * "DEFAULT" and "ALL". + */ + + str = g_string_sized_new (75); + for (diter = &domain_descs[0]; diter->name; diter++) { + /* If it's set for any lower level, it will also be set for LOGL_ERR */ + if (!(diter->num & logging[LOGL_ERR])) + continue; + + if (str->len) + g_string_append_c (str, ','); + g_string_append (str, diter->name); + + /* Check if it's logging at a lower level than the default. */ + for (i = 0; i < log_level; i++) { + if (diter->num & logging[i]) { + g_string_append_printf (str, ":%s", level_names[i]); + break; + } + } + /* Check if it's logging at a higher level than the default. */ + if (!(diter->num & logging[log_level])) { + for (i = log_level + 1; i < LOGL_MAX; i++) { + if (diter->num & logging[i]) { + g_string_append_printf (str, ":%s", level_names[i]); + break; + } + } + } + } + logging_domains_to_string = g_string_free (str, FALSE); + } + return logging_domains_to_string; +} + +const char * +nm_logging_all_domains_to_string (void) +{ + static GString *str; + + if (G_UNLIKELY (!str)) { + const LogDesc *diter; + + str = g_string_new (LOGD_DEFAULT_STRING); + for (diter = &domain_descs[0]; diter->name; diter++) { + g_string_append_c (str, ','); + g_string_append (str, diter->name); + if (diter->num == LOGD_DHCP6) + g_string_append (str, "," LOGD_DHCP_STRING); + else if (diter->num == LOGD_IP6) + g_string_append (str, "," LOGD_IP_STRING); + } + g_string_append (str, "," LOGD_ALL_STRING); + } + + return str->str; +} + +gboolean +nm_logging_enabled (NMLogLevel level, NMLogDomain domain) +{ + g_return_val_if_fail (level < LOGL_MAX, FALSE); + + _ensure_initialized (); + + return !!(logging[level] & domain); +} + +void +_nm_log (const char *file, + guint line, + const char *func, + NMLogLevel level, + NMLogDomain domain, + const char *fmt, + ...) +{ + va_list args; + char *msg; + char *fullmsg = NULL; + GTimeVal tv; + int syslog_level = LOG_INFO; + int g_log_level = G_LOG_LEVEL_INFO; + + g_return_if_fail (level < LOGL_MAX); + + _ensure_initialized (); + + if (!(logging[level] & domain)) + return; + + va_start (args, fmt); + msg = g_strdup_vprintf (fmt, args); + va_end (args); + + switch (level) { + case LOGL_TRACE: + g_get_current_time (&tv); + syslog_level = LOG_DEBUG; + g_log_level = G_LOG_LEVEL_DEBUG; + fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + break; + case LOGL_DEBUG: + g_get_current_time (&tv); + syslog_level = LOG_INFO; + g_log_level = G_LOG_LEVEL_DEBUG; + fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + break; + case LOGL_INFO: + syslog_level = LOG_INFO; + g_log_level = G_LOG_LEVEL_MESSAGE; + fullmsg = g_strconcat (" ", msg, NULL); + break; + case LOGL_WARN: + syslog_level = LOG_WARNING; + g_log_level = G_LOG_LEVEL_WARNING; + fullmsg = g_strconcat (" ", msg, NULL); + break; + case LOGL_ERR: + syslog_level = LOG_ERR; + /* g_log_level is still WARNING, because ERROR is fatal */ + g_log_level = G_LOG_LEVEL_WARNING; + g_get_current_time (&tv); + fullmsg = g_strdup_printf (" [%ld.%06ld] [%s:%u] %s(): %s", tv.tv_sec, tv.tv_usec, file, line, func, msg); + break; + default: + g_assert_not_reached (); + } + + if (syslog_opened) + syslog (syslog_level, "%s", fullmsg); + else + g_log (G_LOG_DOMAIN, g_log_level, "%s", fullmsg); + + g_free (msg); + g_free (fullmsg); +} + +/************************************************************************/ + +static void +nm_log_handler (const gchar *log_domain, + GLogLevelFlags level, + const gchar *message, + gpointer ignored) +{ + int syslog_priority; + + switch (level & G_LOG_LEVEL_MASK) { + case G_LOG_LEVEL_ERROR: + syslog_priority = LOG_CRIT; + break; + case G_LOG_LEVEL_CRITICAL: + syslog_priority = LOG_ERR; + break; + case G_LOG_LEVEL_WARNING: + syslog_priority = LOG_WARNING; + break; + case G_LOG_LEVEL_MESSAGE: + syslog_priority = LOG_NOTICE; + break; + case G_LOG_LEVEL_DEBUG: + syslog_priority = LOG_DEBUG; + break; + case G_LOG_LEVEL_INFO: + default: + syslog_priority = LOG_INFO; + break; + } + + syslog (syslog_priority, "%s", message); +} + +void +nm_logging_syslog_openlog (gboolean debug) +{ + if (debug) + openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER); + else + openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON); + + if (!syslog_opened) { + syslog_opened = TRUE; + + g_log_set_handler (G_LOG_DOMAIN, + G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, + nm_log_handler, + NULL); + } +} + +void +nm_logging_syslog_closelog (void) +{ + if (syslog_opened) + closelog (); +} diff --git a/src/nm-logging.h b/src/nm-logging.h new file mode 100644 index 00000000..4ab2db3a --- /dev/null +++ b/src/nm-logging.h @@ -0,0 +1,159 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2006 - 2012 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __NETWORKMANAGER_LOGGING_H__ +#define __NETWORKMANAGER_LOGGING_H__ + +#ifdef __NM_TEST_UTILS_H__ +#error nm-test-utils.h must be included as last header +#endif + +#include +#include + +#include "nm-utils-internal.h" + +/* Log domains */ +typedef enum { /*< skip >*/ + LOGD_NONE = 0LL, + LOGD_PLATFORM = (1LL << 0), /* Platform services */ + LOGD_RFKILL = (1LL << 1), + LOGD_ETHER = (1LL << 2), + LOGD_WIFI = (1LL << 3), + LOGD_BT = (1LL << 4), + LOGD_MB = (1LL << 5), /* mobile broadband */ + LOGD_DHCP4 = (1LL << 6), + LOGD_DHCP6 = (1LL << 7), + LOGD_PPP = (1LL << 8), + LOGD_WIFI_SCAN = (1LL << 9), + LOGD_IP4 = (1LL << 10), + LOGD_IP6 = (1LL << 11), + LOGD_AUTOIP4 = (1LL << 12), + LOGD_DNS = (1LL << 13), + LOGD_VPN = (1LL << 14), + LOGD_SHARING = (1LL << 15), /* Connection sharing/dnsmasq */ + LOGD_SUPPLICANT = (1LL << 16), /* WiFi and 802.1x */ + LOGD_AGENTS = (1LL << 17), /* Secret agents */ + LOGD_SETTINGS = (1LL << 18), /* Settings */ + LOGD_SUSPEND = (1LL << 19), /* Suspend/Resume */ + LOGD_CORE = (1LL << 20), /* Core daemon and policy stuff */ + LOGD_DEVICE = (1LL << 21), /* Device state and activation */ + LOGD_OLPC = (1LL << 22), + LOGD_WIMAX = (1LL << 23), + LOGD_INFINIBAND = (1LL << 24), + LOGD_FIREWALL = (1LL << 25), + LOGD_ADSL = (1LL << 26), + LOGD_BOND = (1LL << 27), + LOGD_VLAN = (1LL << 28), + LOGD_BRIDGE = (1LL << 29), + LOGD_DBUS_PROPS = (1LL << 30), + LOGD_TEAM = (1LL << 31), + LOGD_CONCHECK = (1LL << 32), + LOGD_DCB = (1LL << 33), /* Data Center Bridging */ + LOGD_DISPATCH = (1LL << 34), + + __LOGD_MAX, + LOGD_ALL = ((__LOGD_MAX - 1LL) << 1) - 1LL, + LOGD_DEFAULT = LOGD_ALL & ~( + LOGD_DBUS_PROPS | + LOGD_WIFI_SCAN | + 0), + + /* aliases: */ + LOGD_DHCP = LOGD_DHCP4 | LOGD_DHCP6, + LOGD_IP = LOGD_IP4 | LOGD_IP6, + LOGD_HW = LOGD_PLATFORM, +} NMLogDomain; + +/* Log levels */ +typedef enum { /*< skip >*/ + LOGL_TRACE, + LOGL_DEBUG, + LOGL_INFO, + LOGL_WARN, + LOGL_ERR, + + LOGL_MAX +} NMLogLevel; + +#define nm_log_err(domain, ...) nm_log (LOGL_ERR, (domain), __VA_ARGS__) +#define nm_log_warn(domain, ...) nm_log (LOGL_WARN, (domain), __VA_ARGS__) +#define nm_log_info(domain, ...) nm_log (LOGL_INFO, (domain), __VA_ARGS__) +#define nm_log_dbg(domain, ...) nm_log (LOGL_DEBUG, (domain), __VA_ARGS__) +#define nm_log_trace(domain, ...) nm_log (LOGL_TRACE, (domain), __VA_ARGS__) + +/* nm_log() only evaluates it's argument list after checking + * whether logging for the given level/domain is enabled. */ +#define nm_log(level, domain, ...) \ + G_STMT_START { \ + if (nm_logging_enabled ((level), (domain))) { \ + _nm_log (__FILE__, __LINE__, G_STRFUNC, (level), (domain), __VA_ARGS__); \ + } \ + } G_STMT_END + + +#define _nm_log_ptr(level, domain, self, ...) \ + nm_log ((level), (domain), "[%p] " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), self _NM_UTILS_MACRO_REST(__VA_ARGS__)) + +/* log a message for an object (with providing a generic @self pointer) */ +#define nm_log_ptr(level, domain, self, ...) \ + G_STMT_START { \ + if ((level) <= LOGL_DEBUG) { \ + _nm_log_ptr ((level), (domain), (self), __VA_ARGS__); \ + } else { \ + nm_log ((level), (domain), __VA_ARGS__); \ + } \ + } G_STMT_END + + +#define _nm_log_obj(level, domain, self, ...) \ + _nm_log_ptr ((level), (domain), (self), __VA_ARGS__) + +/* log a message for an object (with providing a @self pointer to a GObject). + * Contrary to nm_log_ptr(), @self must be a GObject type (or %NULL). + * As of now, nm_log_obj() is identical to nm_log_ptr(), but we might change that */ +#define nm_log_obj(level, domain, self, ...) \ + nm_log_ptr ((level), (domain), (self), __VA_ARGS__) + + +void _nm_log (const char *file, + guint line, + const char *func, + NMLogLevel level, + NMLogDomain domain, + const char *fmt, + ...) __attribute__((__format__ (__printf__, 6, 7))); + +const char *nm_logging_level_to_string (void); +const char *nm_logging_domains_to_string (void); +gboolean nm_logging_enabled (NMLogLevel level, NMLogDomain domain); + +const char *nm_logging_all_levels_to_string (void); +const char *nm_logging_all_domains_to_string (void); + +gboolean nm_logging_setup (const char *level, + const char *domains, + char **bad_domains, + GError **error); +void nm_logging_syslog_openlog (gboolean debug); +void nm_logging_syslog_closelog (void); + +#endif /* __NETWORKMANAGER_LOGGING_H__ */ diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c deleted file mode 100644 index 7f8b3130..00000000 --- a/src/nm-manager-auth.c +++ /dev/null @@ -1,656 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2010 Red Hat, Inc. - */ - -#include -#include -#include -#include - -#if WITH_POLKIT -#include -#endif - -#include "nm-setting-connection.h" -#include "nm-manager-auth.h" -#include "nm-logging.h" -#include "nm-dbus-manager.h" -#include "nm-auth-subject.h" - -struct NMAuthChain { - guint32 refcount; -#if WITH_POLKIT - PolkitAuthority *authority; -#endif - GSList *calls; - GHashTable *data; - - DBusGMethodInvocation *context; - char *owner; - gulong user_uid; - NMAuthSubject *subject; - GError *error; - - guint idle_id; - - NMAuthChainResultFunc done_func; - gpointer user_data; -}; - -typedef struct { - NMAuthChain *chain; - GCancellable *cancellable; - char *permission; - guint call_idle_id; -} AuthCall; - -typedef struct { - gpointer data; - GDestroyNotify destroy; -} ChainData; - -static void -free_data (gpointer data) -{ - ChainData *tmp = data; - - if (tmp->destroy) - tmp->destroy (tmp->data); - memset (tmp, 0, sizeof (ChainData)); - g_free (tmp); -} - -static gboolean -auth_chain_finish (gpointer user_data) -{ - NMAuthChain *self = user_data; - - self->idle_id = 0; - - /* Ensure we say alive across the callback */ - self->refcount++; - self->done_func (self, self->error, self->context, self->user_data); - nm_auth_chain_unref (self); - return FALSE; -} - -#if WITH_POLKIT -static PolkitAuthority * -pk_authority_get (GError **error) -{ - static PolkitAuthority *authority = NULL; - - if (authority == NULL) - authority = polkit_authority_get_sync (NULL, error); - - /* Yes, ref every time; we want to keep the object alive */ - g_warn_if_fail (authority); - return authority ? g_object_ref (authority) : NULL; -} -#endif - -static NMAuthChain * -_auth_chain_new (NMAuthSubject *subject, - const char *dbus_sender, - gulong user_uid, - DBusGMethodInvocation *context, - NMAuthChainResultFunc done_func, - gpointer user_data) -{ - NMAuthChain *self; - - g_return_val_if_fail (subject || user_uid == 0 || dbus_sender, NULL); - - self = g_malloc0 (sizeof (NMAuthChain)); - self->refcount = 1; -#if WITH_POLKIT - self->authority = pk_authority_get (&self->error); -#endif - self->data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_data); - self->done_func = done_func; - self->user_data = user_data; - self->context = context; - - if (subject) { - self->user_uid = nm_auth_subject_get_uid (subject); - self->subject = g_object_ref (subject); - } else { - self->user_uid = user_uid; - self->owner = g_strdup (dbus_sender); - if (user_uid > 0 && !self->owner) { - /* Need an owner */ - g_warn_if_fail (self->owner); - nm_auth_chain_unref (self); - self = NULL; - } - } - - return self; -} - -NMAuthChain * -nm_auth_chain_new_dbus_sender (const char *dbus_sender, - gulong user_uid, - NMAuthChainResultFunc done_func, - gpointer user_data) -{ - return _auth_chain_new (NULL, dbus_sender, user_uid, NULL, done_func, user_data); -} - -/* Creates the NMAuthSubject automatically */ -NMAuthChain * -nm_auth_chain_new_context (DBusGMethodInvocation *context, - NMAuthChainResultFunc done_func, - gpointer user_data) -{ - NMAuthSubject *subject; - NMAuthChain *chain; - - g_return_val_if_fail (context != NULL, NULL); - - subject = nm_auth_subject_new_from_context (context); - if (!subject) - return NULL; - - chain = nm_auth_chain_new_subject (subject, - context, - done_func, - user_data); - g_object_unref (subject); - return chain; -} - -/* Requires an NMAuthSubject */ -NMAuthChain * -nm_auth_chain_new_subject (NMAuthSubject *subject, - DBusGMethodInvocation *context, - NMAuthChainResultFunc done_func, - gpointer user_data) -{ - NMAuthChain *chain; - - g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); - chain = _auth_chain_new (subject, NULL, G_MAXULONG, context, done_func, user_data); - - /* Chains creation from a valid NMAuthSubject cannot fail since the - * subject already has all the necessary auth info. - */ - g_assert (chain); - return chain; -} - -gpointer -nm_auth_chain_get_data (NMAuthChain *self, const char *tag) -{ - ChainData *tmp; - - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (tag != NULL, NULL); - - tmp = g_hash_table_lookup (self->data, tag); - return tmp ? tmp->data : NULL; -} - -/** - * nm_auth_chain_steal_data: - * @self: A #NMAuthChain. - * @tag: A "tag" uniquely identifying the data to steal. - * - * Removes the datum assocated with @tag from the chain's data associations, - * without invoking the association's destroy handler. The caller assumes - * ownership over the returned value. - * - * Returns: the datum originally associated with @tag - */ -gpointer -nm_auth_chain_steal_data (NMAuthChain *self, const char *tag) -{ - ChainData *tmp; - gpointer value = NULL; - - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (tag != NULL, NULL); - - tmp = g_hash_table_lookup (self->data, tag); - if (tmp) { - g_hash_table_steal (self->data, tag); - value = tmp->data; - /* Make sure the destroy handler isn't called when freeing */ - tmp->destroy = NULL; - free_data (tmp); - } - return value; -} - -void -nm_auth_chain_set_data (NMAuthChain *self, - const char *tag, - gpointer data, - GDestroyNotify data_destroy) -{ - ChainData *tmp; - - g_return_if_fail (self != NULL); - g_return_if_fail (tag != NULL); - - if (data == NULL) - g_hash_table_remove (self->data, tag); - else { - tmp = g_malloc0 (sizeof (ChainData)); - tmp->data = data; - tmp->destroy = data_destroy; - - g_hash_table_insert (self->data, g_strdup (tag), tmp); - } -} - -gulong -nm_auth_chain_get_data_ulong (NMAuthChain *self, const char *tag) -{ - gulong *ptr; - - g_return_val_if_fail (self != NULL, 0); - g_return_val_if_fail (tag != NULL, 0); - - ptr = nm_auth_chain_get_data (self, tag); - return *ptr; -} - - -void -nm_auth_chain_set_data_ulong (NMAuthChain *self, - const char *tag, - gulong data) -{ - gulong *ptr; - - g_return_if_fail (self != NULL); - g_return_if_fail (tag != NULL); - - ptr = g_malloc (sizeof (*ptr)); - *ptr = data; - nm_auth_chain_set_data (self, tag, ptr, g_free); -} - -NMAuthCallResult -nm_auth_chain_get_result (NMAuthChain *self, const char *permission) -{ - g_return_val_if_fail (self != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); - g_return_val_if_fail (permission != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); - - return GPOINTER_TO_UINT (nm_auth_chain_get_data (self, permission)); -} - -static void -nm_auth_chain_check_done (NMAuthChain *self) -{ - g_return_if_fail (self != NULL); - - if (g_slist_length (self->calls) == 0) { - g_assert (self->idle_id == 0); - self->idle_id = g_idle_add (auth_chain_finish, self); - } -} - -static void -nm_auth_chain_remove_call (NMAuthChain *self, AuthCall *call) -{ - g_return_if_fail (self != NULL); - g_return_if_fail (call != NULL); - - self->calls = g_slist_remove (self->calls, call); -} - -static AuthCall * -auth_call_new (NMAuthChain *chain, const char *permission) -{ - AuthCall *call; - - call = g_malloc0 (sizeof (AuthCall)); - call->chain = chain; - call->permission = g_strdup (permission); - chain->calls = g_slist_append (chain->calls, call); - return call; -} - -static void -auth_call_free (AuthCall *call) -{ - g_free (call->permission); - g_clear_object (&call->cancellable); - g_free (call); -} - -/* This can get used from scheduled idles, hence the boolean return */ -static gboolean -auth_call_complete (AuthCall *call) -{ - nm_auth_chain_remove_call (call->chain, call); - nm_auth_chain_check_done (call->chain); - auth_call_free (call); - return FALSE; -} - -static void -auth_call_cancel (gpointer user_data) -{ - AuthCall *call = user_data; - - if (call->cancellable) { - /* we don't free call immediately. Instead we cancel the async operation - * and set cancellable to NULL. pk_call_cb() will check for this and - * do the final cleanup. */ - g_cancellable_cancel (call->cancellable); - g_clear_object (&call->cancellable); - } else { - g_source_remove (call->call_idle_id); - auth_call_free (call); - } -} - -#if WITH_POLKIT -static void -pk_call_cb (GObject *object, GAsyncResult *result, gpointer user_data) -{ - AuthCall *call = user_data; - PolkitAuthorizationResult *pk_result; - GError *error = NULL; - - pk_result = polkit_authority_check_authorization_finish ((PolkitAuthority *) object, result, &error); - - /* If the call is already canceled do nothing */ - if (!call->cancellable) { - g_clear_error (&error); - g_clear_object (&pk_result); - auth_call_free (call); - return; - } - - if (error) { - if (!call->chain->error) - call->chain->error = g_error_copy (error); - - nm_log_warn (LOGD_CORE, "error requesting auth for %s: (%d) %s", - call->permission, error->code, error->message); - g_clear_error (&error); - } else { - guint call_result = NM_AUTH_CALL_RESULT_UNKNOWN; - - if (polkit_authorization_result_get_is_authorized (pk_result)) { - /* Caller has the permission */ - call_result = NM_AUTH_CALL_RESULT_YES; - } else if (polkit_authorization_result_get_is_challenge (pk_result)) { - /* Caller could authenticate to get the permission */ - call_result = NM_AUTH_CALL_RESULT_AUTH; - } else - call_result = NM_AUTH_CALL_RESULT_NO; - - nm_auth_chain_set_data (call->chain, call->permission, GUINT_TO_POINTER (call_result), NULL); - g_object_unref (pk_result); - } - - auth_call_complete (call); -} - -static void -auth_call_schedule_complete_with_error (AuthCall *call, const char *msg) -{ - if (!call->chain->error) - call->chain->error = g_error_new_literal (DBUS_GERROR, DBUS_GERROR_FAILED, msg); - call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); -} - -static gboolean -_add_call_polkit (NMAuthChain *self, - const char *permission, - gboolean allow_interaction) -{ - PolkitSubject *subject; - PolkitCheckAuthorizationFlags flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; - AuthCall *call; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (self->owner || self->subject, FALSE); - g_return_val_if_fail (permission != NULL, FALSE); - - call = auth_call_new (self, permission); - - if (self->authority == NULL) { - /* No polkit, no authorization */ - auth_call_schedule_complete_with_error (call, "PolicyKit not running"); - return FALSE; - } - - if (self->subject) { - subject = g_object_ref (nm_auth_subject_get_polkit_subject (self->subject)); - g_assert (subject); - } else { - g_assert (self->owner); - subject = polkit_system_bus_name_new (self->owner); - if (!subject) { - auth_call_schedule_complete_with_error (call, "Failed to create polkit subject"); - return FALSE; - } - } - - if (allow_interaction) - flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; - - call->cancellable = g_cancellable_new (); - polkit_authority_check_authorization (self->authority, - subject, - permission, - NULL, - flags, - call->cancellable, - pk_call_cb, - call); - g_object_unref (subject); - return TRUE; -} -#endif - -gboolean -nm_auth_chain_add_call (NMAuthChain *self, - const char *permission, - gboolean allow_interaction) -{ - AuthCall *call; - - g_return_val_if_fail (self != NULL, FALSE); - -#if WITH_POLKIT - /* Non-root always gets authenticated when using polkit */ - if (self->user_uid > 0) - return _add_call_polkit (self, permission, allow_interaction); -#endif - - /* Root user or non-polkit always gets the permission */ - call = auth_call_new (self, permission); - nm_auth_chain_set_data (self, permission, GUINT_TO_POINTER (NM_AUTH_CALL_RESULT_YES), NULL); - call->call_idle_id = g_idle_add ((GSourceFunc) auth_call_complete, call); - return TRUE; -} - -void -nm_auth_chain_unref (NMAuthChain *self) -{ - g_return_if_fail (self != NULL); - - self->refcount--; - if (self->refcount > 0) - return; - - if (self->idle_id) - g_source_remove (self->idle_id); - -#if WITH_POLKIT - if (self->authority) - g_object_unref (self->authority); -#endif - g_free (self->owner); - g_object_unref (self->subject); - - g_slist_free_full (self->calls, auth_call_cancel); - - g_clear_error (&self->error); - g_hash_table_destroy (self->data); - - memset (self, 0, sizeof (NMAuthChain)); - g_free (self); -} - -/************ utils **************/ - -gboolean -nm_auth_uid_in_acl (NMConnection *connection, - NMSessionMonitor *smon, - gulong uid, - char **out_error_desc) -{ - NMSettingConnection *s_con; - const char *user = NULL; - GError *local = NULL; - - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (smon != NULL, FALSE); - - /* Root gets a free pass */ - if (0 == uid) - return TRUE; - - /* Reject the request if the request comes from no session at all */ - if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { - if (out_error_desc) { - *out_error_desc = g_strdup_printf ("No session found for uid %lu (%s)", - uid, - local && local->message ? local->message : "unknown"); - } - g_clear_error (&local); - return FALSE; - } - - if (!user) { - if (out_error_desc) - *out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid); - return FALSE; - } - - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) { - /* This can only happen when called from AddAndActivate, so we know - * the user will be authorized when the connection is completed. - */ - return TRUE; - } - - /* Match the username returned by the session check to a user in the ACL */ - if (!nm_setting_connection_permissions_user_allowed (s_con, user)) { - if (out_error_desc) - *out_error_desc = g_strdup_printf ("uid %lu has no permission to perform this operation", uid); - return FALSE; - } - - return TRUE; -} - -typedef struct { - GDestroyNotify changed_callback; - gpointer changed_data; -} PkChangedInfo; - -static GSList *funcs = NULL; - -#if WITH_POLKIT -static void -pk_authority_changed_cb (GObject *object, gpointer unused) -{ - GSList *iter; - - for (iter = funcs; iter; iter = g_slist_next (iter)) { - PkChangedInfo *info = iter->data; - - info->changed_callback (info->changed_data); - } -} -#endif - -void -nm_auth_changed_func_register (GDestroyNotify callback, gpointer callback_data) -{ -#if WITH_POLKIT - PolkitAuthority *authority; - static guint32 changed_id = 0; -#endif - PkChangedInfo *info; - GSList *iter; - gboolean found = FALSE; - -#if WITH_POLKIT - authority = pk_authority_get (NULL); - if (!authority) - return; - - /* Hook up the changed signal the first time a callback is registered */ - if (changed_id == 0) { - changed_id = g_signal_connect (authority, - "changed", - G_CALLBACK (pk_authority_changed_cb), - &funcs); - } -#endif - - /* No duplicates */ - for (iter = funcs; iter; iter = g_slist_next (iter)) { - info = iter->data; - if ((callback == info->changed_callback) && (callback_data == info->changed_data)) { - found = TRUE; - break; - } - } - - g_warn_if_fail (found == FALSE); - if (found == FALSE) { - info = g_malloc0 (sizeof (*info)); - info->changed_callback = callback; - info->changed_data = callback_data; - funcs = g_slist_append (funcs, info); - } - -#if WITH_POLKIT - g_object_unref (authority); -#endif -} - -void -nm_auth_changed_func_unregister (GDestroyNotify callback, gpointer callback_data) -{ - GSList *iter; - - for (iter = funcs; iter; iter = g_slist_next (iter)) { - PkChangedInfo *info = iter->data; - - if ((callback == info->changed_callback) && (callback_data == info->changed_data)) { - g_free (info); - funcs = g_slist_delete_link (funcs, iter); - break; - } - } -} - diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h deleted file mode 100644 index 43dd6398..00000000 --- a/src/nm-manager-auth.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2010 Red Hat, Inc. - */ - -#ifndef NM_MANAGER_AUTH_H -#define NM_MANAGER_AUTH_H - -#include -#include - -#include -#include "nm-dbus-manager.h" -#include "nm-session-monitor.h" -#include "nm-auth-subject.h" - -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" -#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax" -#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" -#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" -#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" -#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" -#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" -#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" - - -typedef struct NMAuthChain NMAuthChain; - -typedef enum { - NM_AUTH_CALL_RESULT_UNKNOWN, - NM_AUTH_CALL_RESULT_YES, - NM_AUTH_CALL_RESULT_AUTH, - NM_AUTH_CALL_RESULT_NO, -} NMAuthCallResult; - -typedef void (*NMAuthChainResultFunc) (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data); - -NMAuthChain *nm_auth_chain_new_dbus_sender (const char *dbus_sender, - gulong user_uid, - NMAuthChainResultFunc done_func, - gpointer user_data); - -NMAuthChain *nm_auth_chain_new_context (DBusGMethodInvocation *context, - NMAuthChainResultFunc done_func, - gpointer user_data); - -NMAuthChain *nm_auth_chain_new_subject (NMAuthSubject *subject, - DBusGMethodInvocation *context, - NMAuthChainResultFunc done_func, - gpointer user_data); - -gpointer nm_auth_chain_get_data (NMAuthChain *chain, const char *tag); - -gpointer nm_auth_chain_steal_data (NMAuthChain *chain, const char *tag); - -void nm_auth_chain_set_data (NMAuthChain *chain, - const char *tag, - gpointer data, - GDestroyNotify data_destroy); - -void nm_auth_chain_set_data_ulong (NMAuthChain *chain, - const char *tag, - gulong data); - -gulong nm_auth_chain_get_data_ulong (NMAuthChain *chain, const char *tag); - -NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain, - const char *permission); - -gboolean nm_auth_chain_add_call (NMAuthChain *chain, - const char *permission, - gboolean allow_interaction); - -void nm_auth_chain_unref (NMAuthChain *chain); - -/* Caller must free returned error description */ -gboolean nm_auth_uid_in_acl (NMConnection *connection, - NMSessionMonitor *smon, - gulong uid, - char **out_error_desc); - -void nm_auth_changed_func_register (GDestroyNotify callback, gpointer callback_data); - -void nm_auth_changed_func_unregister (GDestroyNotify callback, gpointer callback_data); - -#endif /* NM_MANAGER_AUTH_H */ - diff --git a/src/nm-manager-glue.h b/src/nm-manager-glue.h index 1f365b0e..d907f4d2 100644 --- a/src/nm-manager-glue.h +++ b/src/nm-manager-glue.h @@ -411,6 +411,6 @@ const DBusGObjectInfo dbus_glib_nm_manager_object_info = { 1, 12, "org.freedesktop.NetworkManager\0GetDevices\0S\0devices\0O\0F\0N\0ao\0\0org.freedesktop.NetworkManager\0GetDeviceByIpIface\0S\0iface\0I\0s\0device\0O\0F\0N\0o\0\0org.freedesktop.NetworkManager\0ActivateConnection\0A\0connection\0I\0o\0device\0I\0o\0specific_object\0I\0o\0active_connection\0O\0F\0N\0o\0\0org.freedesktop.NetworkManager\0AddAndActivateConnection\0A\0connection\0I\0a{sa{sv}}\0device\0I\0o\0specific_object\0I\0o\0path\0O\0F\0N\0o\0active_connection\0O\0F\0N\0o\0\0org.freedesktop.NetworkManager\0DeactivateConnection\0A\0active_connection\0I\0o\0\0org.freedesktop.NetworkManager\0Sleep\0A\0sleep\0I\0b\0\0org.freedesktop.NetworkManager\0Enable\0A\0enable\0I\0b\0\0org.freedesktop.NetworkManager\0GetPermissions\0A\0permissions\0O\0F\0N\0a{ss}\0\0org.freedesktop.NetworkManager\0SetLogging\0A\0level\0I\0s\0domains\0I\0s\0\0org.freedesktop.NetworkManager\0GetLogging\0S\0level\0O\0F\0N\0s\0domains\0O\0F\0N\0s\0\0org.freedesktop.NetworkManager\0CheckConnectivity\0A\0connectivity\0O\0F\0N\0u\0\0org.freedesktop.NetworkManager\0state\0S\0state\0O\0F\0N\0u\0\0\0", "org.freedesktop.NetworkManager\0CheckPermissions\0org.freedesktop.NetworkManager\0StateChanged\0org.freedesktop.NetworkManager\0PropertiesChanged\0org.freedesktop.NetworkManager\0DeviceAdded\0org.freedesktop.NetworkManager\0DeviceRemoved\0\0", -"org.freedesktop.NetworkManager\0Devices\0devices\0read\0org.freedesktop.NetworkManager\0NetworkingEnabled\0networking_enabled\0read\0org.freedesktop.NetworkManager\0WirelessEnabled\0wireless_enabled\0readwrite\0org.freedesktop.NetworkManager\0WirelessHardwareEnabled\0wireless_hardware_enabled\0read\0org.freedesktop.NetworkManager\0WwanEnabled\0wwan_enabled\0readwrite\0org.freedesktop.NetworkManager\0WwanHardwareEnabled\0wwan_hardware_enabled\0read\0org.freedesktop.NetworkManager\0WimaxEnabled\0wimax_enabled\0readwrite\0org.freedesktop.NetworkManager\0WimaxHardwareEnabled\0wimax_hardware_enabled\0read\0org.freedesktop.NetworkManager\0ActiveConnections\0active_connections\0read\0org.freedesktop.NetworkManager\0PrimaryConnection\0primary_connection\0read\0org.freedesktop.NetworkManager\0ActivatingConnection\0activating_connection\0read\0org.freedesktop.NetworkManager\0Startup\0startup\0read\0org.freedesktop.NetworkManager\0Version\0version\0read\0org.freedesktop.NetworkManager\0State\0state\0read\0org.freedesktop.NetworkManager\0Connectivity\0connectivity\0read\0\0" +"org.freedesktop.NetworkManager\0Devices\0devices\0read\0org.freedesktop.NetworkManager\0NetworkingEnabled\0networking_enabled\0read\0org.freedesktop.NetworkManager\0WirelessEnabled\0wireless_enabled\0readwrite\0org.freedesktop.NetworkManager\0WirelessHardwareEnabled\0wireless_hardware_enabled\0read\0org.freedesktop.NetworkManager\0WwanEnabled\0wwan_enabled\0readwrite\0org.freedesktop.NetworkManager\0WwanHardwareEnabled\0wwan_hardware_enabled\0read\0org.freedesktop.NetworkManager\0WimaxEnabled\0wimax_enabled\0readwrite\0org.freedesktop.NetworkManager\0WimaxHardwareEnabled\0wimax_hardware_enabled\0read\0org.freedesktop.NetworkManager\0ActiveConnections\0active_connections\0read\0org.freedesktop.NetworkManager\0PrimaryConnection\0primary_connection\0read\0org.freedesktop.NetworkManager\0PrimaryConnectionType\0primary_connection_type\0read\0org.freedesktop.NetworkManager\0ActivatingConnection\0activating_connection\0read\0org.freedesktop.NetworkManager\0Startup\0startup\0read\0org.freedesktop.NetworkManager\0Version\0version\0read\0org.freedesktop.NetworkManager\0State\0state\0read\0org.freedesktop.NetworkManager\0Connectivity\0connectivity\0read\0\0" }; diff --git a/src/nm-manager.c b/src/nm-manager.c index 09a1985a..7e81afa5 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -19,10 +19,9 @@ * Copyright (C) 2007 - 2012 Red Hat, Inc. */ -#include +#include "config.h" #include -#include #include #include #include @@ -34,42 +33,33 @@ #include #include +#include "gsystem-local-alloc.h" #include "nm-glib-compat.h" #include "nm-manager.h" #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-vpn-manager.h" #include "nm-device.h" -#include "nm-device-ethernet.h" -#include "nm-device-infiniband.h" -#include "nm-device-bond.h" -#include "nm-device-team.h" -#include "nm-device-bridge.h" -#include "nm-device-vlan.h" #include "nm-device-generic.h" -#include "nm-device-veth.h" -#include "nm-device-tun.h" -#include "nm-device-macvlan.h" -#include "nm-device-vxlan.h" -#include "nm-device-gre.h" -#include "nm-setting-connection.h" -#include "nm-setting-wireless.h" -#include "nm-setting-vpn.h" #include "nm-dbus-glib-types.h" #include "nm-platform.h" #include "nm-rfkill-manager.h" #include "nm-dhcp-manager.h" #include "nm-settings.h" #include "nm-settings-connection.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" +#include "nm-auth-manager.h" #include "NetworkManagerUtils.h" -#include "nm-utils.h" #include "nm-device-factory.h" #include "nm-enum-types.h" #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" +#include "nm-config.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" @@ -128,8 +118,7 @@ static void impl_manager_check_connectivity (NMManager *manager, #include "nm-manager-glue.h" -static void add_device (NMManager *self, NMDevice *device, gboolean generate_con); -static void remove_device (NMManager *self, NMDevice *device, gboolean quitting); +static void add_device (NMManager *self, NMDevice *device, gboolean try_assume); static NMActiveConnection *_new_active_connection (NMManager *self, NMConnection *connection, @@ -198,7 +187,7 @@ typedef struct { gboolean sleeping; gboolean net_enabled; - NMVPNManager *vpn_manager; + NMVpnManager *vpn_manager; DBusGProxy *aipd_proxy; NMSleepMonitor *sleep_monitor; @@ -226,6 +215,7 @@ enum { USER_PERMISSIONS_CHANGED, ACTIVE_CONNECTION_ADDED, ACTIVE_CONNECTION_REMOVED, + CONFIGURE_QUIT, LAST_SIGNAL }; @@ -247,6 +237,7 @@ enum { PROP_ACTIVE_CONNECTIONS, PROP_CONNECTIVITY, PROP_PRIMARY_CONNECTION, + PROP_PRIMARY_CONNECTION_TYPE, PROP_ACTIVATING_CONNECTION, PROP_DEVICES, @@ -258,19 +249,6 @@ enum { }; -/************************************************************************/ - -#define NM_MANAGER_ERROR (nm_manager_error_quark ()) - -static GQuark -nm_manager_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-manager-error"); - return quark; -} - /************************************************************************/ static void active_connection_state_changed (NMActiveConnection *active, @@ -291,11 +269,28 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) /* FIXME: switch to a GList for faster removal */ found = g_slist_find (priv->active_connections, active); if (found) { + NMConnection *connection; + priv->active_connections = g_slist_remove (priv->active_connections, active); g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active); g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self); g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self); + + if ( nm_active_connection_get_assumed (active) + && (connection = nm_active_connection_get_connection (active)) + && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + g_object_ref (connection); + else + connection = NULL; + g_object_unref (active); + + if (connection) { + nm_log_dbg (LOGD_DEVICE, "Assumed connection disconnected. Deleting generated connection '%s' (%s)", + nm_connection_get_id (connection), nm_connection_get_uuid (connection)); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); + g_object_unref (connection); + } } return found && notify; @@ -496,24 +491,6 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path) return NULL; } -NMDevice * -nm_manager_get_device_by_master (NMManager *manager, const char *master, const char *driver) -{ - GSList *iter; - - g_return_val_if_fail (master != NULL, NULL); - - for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - NMDevice *device = NM_DEVICE (iter->data); - - if (!strcmp (nm_device_get_iface (device), master) && - (!driver || !strcmp (nm_device_get_driver (device), driver))) - return device; - } - - return NULL; -} - NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex) { @@ -731,6 +708,9 @@ check_if_startup_complete (NMManager *self) g_signal_handlers_disconnect_by_func (dev, G_CALLBACK (device_has_pending_action_changed), self); } + + if (nm_config_get_configure_and_quit (nm_config_get ())) + g_signal_emit (self, signals[CONFIGURE_QUIT], 0); } static void @@ -742,11 +722,17 @@ device_has_pending_action_changed (NMDevice *device, } static void -remove_device (NMManager *manager, NMDevice *device, gboolean quitting) +remove_device (NMManager *manager, + NMDevice *device, + gboolean quitting, + gboolean allow_unmanage) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - if (nm_device_get_managed (device)) { + nm_log_dbg (LOGD_DEVICE, "(%s): removing device (allow_unmanage %d, managed %d)", + nm_device_get_iface (device), allow_unmanage, nm_device_get_managed (device)); + + if (allow_unmanage && nm_device_get_managed (device)) { NMActRequest *req = nm_device_get_act_request (device); gboolean unmanage = FALSE; @@ -767,6 +753,8 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) nm_device_set_unmanaged_quitting (device); else nm_device_set_unmanaged (device, NM_UNMANAGED_INTERNAL, TRUE, NM_DEVICE_STATE_REASON_REMOVED); + } else if (quitting && nm_config_get_configure_and_quit (nm_config_get ())) { + nm_device_spawn_iface_helper (device); } } @@ -777,6 +765,7 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_notify (G_OBJECT (manager), NM_MANAGER_DEVICES); + nm_device_removed (device); nm_dbus_manager_unregister_object (priv->dbus_mgr, device); g_object_unref (device); @@ -787,7 +776,7 @@ remove_device (NMManager *manager, NMDevice *device, gboolean quitting) static void device_removed_cb (NMDevice *device, gpointer user_data) { - remove_device (NM_MANAGER (user_data), device, FALSE); + remove_device (NM_MANAGER (user_data), device, FALSE, TRUE); } static void @@ -842,11 +831,10 @@ nm_manager_get_state (NMManager *manager) /*******************************************************************/ static NMDevice * -get_device_from_hwaddr (NMManager *self, const GByteArray *setting_mac) +get_device_from_hwaddr (NMManager *self, const char *setting_mac) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - const guint8 *device_mac; - guint device_mac_len; + const char *device_mac; GSList *iter; if (!setting_mac) @@ -855,9 +843,10 @@ get_device_from_hwaddr (NMManager *self, const GByteArray *setting_mac) for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *device = iter->data; - device_mac = nm_device_get_hw_address (iter->data, &device_mac_len); - if ( setting_mac->len == device_mac_len - && memcmp (setting_mac->data, device_mac, device_mac_len) == 0) + device_mac = nm_device_get_hw_address (iter->data); + if (!device_mac) + continue; + if (nm_utils_hwaddr_matches (setting_mac, -1, device_mac, -1)) return device; } return NULL; @@ -873,7 +862,7 @@ find_vlan_parent (NMManager *self, NMConnection *parent_connection; const char *parent_iface; NMDevice *parent = NULL; - const GByteArray *setting_mac; + const char *setting_mac; GSList *iter; /* The 'parent' property could be given by an interface name, a @@ -926,7 +915,7 @@ find_infiniband_parent (NMManager *self, NMSettingInfiniband *s_infiniband; const char *parent_iface; NMDevice *parent = NULL; - const GByteArray *setting_mac; + const char *setting_mac; s_infiniband = nm_connection_get_setting_infiniband (connection); g_return_val_if_fail (s_infiniband != NULL, NULL); @@ -961,101 +950,68 @@ get_virtual_iface_name (NMManager *self, NMDevice **out_parent) { NMDevice *parent = NULL; + const char *ifname; if (out_parent) *out_parent = NULL; - if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) - return g_strdup (nm_connection_get_virtual_iface_name (connection)); - - if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) - return g_strdup (nm_connection_get_virtual_iface_name (connection)); + if (!nm_connection_is_virtual (connection)) + return NULL; - if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) - return g_strdup (nm_connection_get_virtual_iface_name (connection)); + ifname = nm_connection_get_interface_name (connection); if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { NMSettingVlan *s_vlan; - const char *ifname; char *vname; s_vlan = nm_connection_get_setting_vlan (connection); g_return_val_if_fail (s_vlan != NULL, NULL); parent = find_vlan_parent (self, connection); - if (parent) { - ifname = nm_connection_get_virtual_iface_name (connection); - - if (!nm_device_supports_vlans (parent)) { - nm_log_warn (LOGD_DEVICE, "(%s): No support for VLANs on interface %s of type %s", - ifname ? ifname : nm_connection_get_id (connection), - nm_device_get_ip_iface (parent), - nm_device_get_type_desc (parent)); - return NULL; - } + if (!parent) + return NULL; - /* If the connection doesn't specify the interface name for the VLAN - * device, we create one for it using the VLAN ID and the parent - * interface's name. - */ - if (ifname) - vname = g_strdup (ifname); - else { - vname = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), - nm_setting_vlan_get_id (s_vlan)); - } - if (out_parent) - *out_parent = parent; - return vname; + if (!nm_device_supports_vlans (parent)) { + nm_log_warn (LOGD_DEVICE, "(%s): No support for VLANs on interface %s of type %s", + ifname ? ifname : nm_connection_get_id (connection), + nm_device_get_ip_iface (parent), + nm_device_get_type_desc (parent)); + return NULL; } - } - - if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { - const char *ifname; - char *name; - parent = find_infiniband_parent (self, connection); - if (parent) { - ifname = nm_connection_get_virtual_iface_name (connection); - if (ifname) - name = g_strdup (ifname); - else { - NMSettingInfiniband *s_infiniband; - int p_key; - - ifname = nm_device_get_iface (parent); - s_infiniband = nm_connection_get_setting_infiniband (connection); - p_key = nm_setting_infiniband_get_p_key (s_infiniband); - name = g_strdup_printf ("%s.%04x", ifname, p_key); - } - if (out_parent) - *out_parent = parent; - return name; + /* If the connection doesn't specify the interface name for the VLAN + * device, we create one for it using the VLAN ID and the parent + * interface's name. + */ + if (ifname) + vname = g_strdup (ifname); + else { + vname = nm_utils_new_vlan_name (nm_device_get_ip_iface (parent), + nm_setting_vlan_get_id (s_vlan)); } + if (out_parent) + *out_parent = parent; + return vname; } - return NULL; -} - -static gboolean -connection_needs_virtual_device (NMConnection *connection) -{ - if ( nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME) - || nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) - return TRUE; - if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { NMSettingInfiniband *s_infiniband; + parent = find_infiniband_parent (self, connection); + if (!parent) + return NULL; + s_infiniband = nm_connection_get_setting_infiniband (connection); - g_return_val_if_fail (s_infiniband != NULL, FALSE); - if (nm_setting_infiniband_get_p_key (s_infiniband) != -1) - return TRUE; + if (out_parent) + *out_parent = parent; + return g_strdup (nm_setting_infiniband_get_virtual_interface_name (s_infiniband)); } - return FALSE; + /* For any other virtual connection, NMSettingConnection:interface-name is + * the virtual device name. + */ + g_return_val_if_fail (ifname != NULL, NULL); + return g_strdup (ifname); } /***************************/ @@ -1074,9 +1030,11 @@ static NMDevice * system_create_virtual_device (NMManager *self, NMConnection *connection) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GError *error = NULL; GSList *iter; char *iface = NULL; NMDevice *device = NULL, *parent = NULL; + gboolean nm_owned = FALSE; iface = get_virtual_iface_name (self, connection, &parent); if (!iface) { @@ -1100,21 +1058,34 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) */ priv->ignore_link_added_cb++; - if (nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) { - device = nm_device_bond_new_for_connection (connection); - } else if (nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) { - device = nm_device_team_new_for_connection (connection); - } else if (nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) { - device = nm_device_bridge_new_for_connection (connection); - } else if (nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) { - device = nm_device_vlan_new_for_connection (connection, parent); - } else if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) { - device = nm_device_infiniband_new_partition (connection, parent); + nm_owned = !nm_platform_link_exists (iface); + + for (iter = priv->factories; iter; iter = iter->next) { + device = nm_device_factory_create_virtual_device_for_connection (NM_DEVICE_FACTORY (iter->data), + connection, + parent, + &error); + if (device || error) { + if (device) + g_assert_no_error (error); + else { + nm_log_err (LOGD_DEVICE, "(%s) failed to create virtual device: %s", + nm_connection_get_id (connection), error ? error->message : "(unknown error)"); + g_clear_error (&error); + } + break; + } } if (device) { - nm_device_set_nm_owned (device); - add_device (self, device, FALSE); + if (nm_owned) + nm_device_set_nm_owned (device); + + /* If it was created by NM there's no connection to assume, but if it + * previously existed there might be one. + */ + add_device (self, device, !nm_owned); + g_object_unref (device); } @@ -1138,7 +1109,7 @@ system_create_virtual_devices (NMManager *self) NMConnection *connection = iter->data; /* We only create a virtual interface if the connection can autoconnect */ - if ( connection_needs_virtual_device (connection) + if ( nm_connection_is_virtual (connection) && nm_settings_connection_can_autoconnect (NM_SETTINGS_CONNECTION (connection))) system_create_virtual_device (self, connection); } @@ -1152,7 +1123,7 @@ connection_added (NMSettings *settings, { NMConnection *connection = NM_CONNECTION (settings_connection); - if (connection_needs_virtual_device (connection)) { + if (nm_connection_is_virtual (connection)) { NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -1481,7 +1452,7 @@ device_auth_request_cb (NMDevice *device, NMAuthChain *chain; /* Validate the caller */ - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -1490,10 +1461,10 @@ device_auth_request_cb (NMDevice *device, } /* Ensure the subject has permissions for this connection */ - if (connection && !nm_auth_uid_in_acl (connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (connection && !nm_auth_is_subject_in_acl (connection, + nm_session_monitor_get (), + subject, + &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); @@ -1524,17 +1495,6 @@ done: g_clear_error (&error); } -/* This should really be moved to gsystem. */ -#define free_slist __attribute__ ((cleanup(local_slist_free))) -static void -local_slist_free (void *loc) -{ - GSList **location = loc; - - if (location) - g_slist_free (*location); -} - static gboolean match_connection_filter (NMConnection *connection, gpointer user_data) { @@ -1545,28 +1505,52 @@ match_connection_filter (NMConnection *connection, gpointer user_data) * get_existing_connection: * @manager: #NMManager instance * @device: #NMDevice instance + * @out_generated: (allow-none): return TRUE, if the connection was generated. * * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if * the device does not support assuming existing connections. */ static NMConnection * -get_existing_connection (NMManager *manager, NMDevice *device) +get_existing_connection (NMManager *manager, NMDevice *device, gboolean *out_generated) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - free_slist GSList *connections = nm_manager_get_activatable_connections (manager); + gs_free_slist GSList *connections = nm_manager_get_activatable_connections (manager); NMConnection *connection = NULL, *matched; NMSettingsConnection *added = NULL; GError *error = NULL; + NMDevice *master = NULL; + int ifindex = nm_device_get_ifindex (device); + + if (out_generated) + *out_generated = FALSE; nm_device_capture_initial_config (device); + if (ifindex) { + int master_ifindex = nm_platform_link_get_master (ifindex); + + if (master_ifindex) { + master = nm_manager_get_device_by_ifindex (manager, master_ifindex); + if (!master) { + nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before its master (%s/%d)", + nm_device_get_iface (device), nm_platform_link_get_name (master_ifindex), master_ifindex); + return NULL; + } + if (!nm_device_get_act_request (master)) { + nm_log_dbg (LOGD_DEVICE, "(%s): cannot generate connection for slave before master %s activates", + nm_device_get_iface (device), nm_device_get_iface (master)); + return NULL; + } + } + } + /* The core of the API is nm_device_generate_connection() function and * update_connection() virtual method and the convenient connection_type * class attribute. Subclasses supporting the new API must have * update_connection() implemented, otherwise nm_device_generate_connection() * returns NULL. */ - connection = nm_device_generate_connection (device); + connection = nm_device_generate_connection (device, master); if (!connection) return NULL; @@ -1598,9 +1582,14 @@ get_existing_connection (NMManager *manager, NMDevice *device) nm_connection_get_id (connection)); added = nm_settings_add_connection (priv->settings, connection, FALSE, &error); - if (added) - nm_settings_connection_set_nm_generated (added); - else { + if (added) { + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, + TRUE); + if (out_generated) + *out_generated = TRUE; + } else { nm_log_warn (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s", nm_device_get_iface (device), nm_connection_get_id (connection), @@ -1657,40 +1646,86 @@ assume_connection (NMManager *self, NMDevice *device, NMConnection *connection) return TRUE; } -static void +static gboolean recheck_assume_connection (NMDevice *device, gpointer user_data) { - NMManager *self = user_data; + NMManager *self = NM_MANAGER (user_data); NMConnection *connection; - gboolean was_unmanaged = FALSE; + gboolean was_unmanaged = FALSE, success, generated; + NMDeviceState state; if (manager_sleeping (self)) - return; - if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER)) - return; + return FALSE; + if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER) || + nm_device_get_unmanaged_flag (device, NM_UNMANAGED_INTERNAL) || + nm_device_get_unmanaged_flag (device, NM_UNMANAGED_EXTERNAL_DOWN) || + nm_device_get_unmanaged_flag (device, NM_UNMANAGED_PARENT)) + return FALSE; - connection = get_existing_connection (self, device); + state = nm_device_get_state (device); + if (state > NM_DEVICE_STATE_DISCONNECTED) + return FALSE; + + connection = get_existing_connection (self, device, &generated); if (!connection) { nm_log_dbg (LOGD_DEVICE, "(%s): can't assume; no connection", nm_device_get_iface (device)); - return; + return FALSE; } - if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) { + if (state == NM_DEVICE_STATE_UNMANAGED) { was_unmanaged = TRUE; nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); } - if (!assume_connection (self, device, connection)) { + success = assume_connection (self, device, connection); + if (!success) { if (was_unmanaged) { nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - nm_device_state_changed (device, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_REASON_CONFIG_FAILED); + + /* Return default-unmanaged devices to their original state */ + if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_DEFAULT)) { + nm_device_state_changed (device, + NM_DEVICE_STATE_UNMANAGED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + } + } + + if (generated) { + nm_log_dbg (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection", + nm_device_get_iface (device)); + + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); + } + } + + return success; +} + +static void +device_ip_iface_changed (NMDevice *device, + GParamSpec *pspec, + NMManager *self) +{ + const char *ip_iface = nm_device_get_ip_iface (device); + GSList *iter; + + /* Remove NMDevice objects that are actually child devices of others, + * when the other device finally knows its IP interface name. For example, + * remove the PPP interface that's a child of a WWAN device, since it's + * not really a standalone NMDevice. + */ + for (iter = NM_MANAGER_GET_PRIVATE (self)->devices; iter; iter = iter->next) { + NMDevice *candidate = NM_DEVICE (iter->data); + + if ( candidate != device + && g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0) { + remove_device (self, candidate, FALSE, FALSE); + break; } } } @@ -1699,22 +1734,22 @@ recheck_assume_connection (NMDevice *device, gpointer user_data) * add_device: * @self: the #NMManager * @device: the #NMDevice to add - * @generate_con: %TRUE if existing connection (if any) should be assumed + * @try_assume: %TRUE if existing connection (if any) should be assumed * * If successful, this function will increase the references count of @device. * Callers should decrease the reference count. */ static void -add_device (NMManager *self, NMDevice *device, gboolean generate_con) +add_device (NMManager *self, NMDevice *device, gboolean try_assume) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const char *iface, *driver, *type_desc; const GSList *unmanaged_specs; gboolean user_unmanaged, sleeping; - NMConnection *connection = NULL; gboolean enabled = FALSE; RfKillType rtype; GSList *iter, *remove = NULL; + gboolean connection_assumed = FALSE; /* No duplicates */ if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device))) @@ -1733,7 +1768,7 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) remove = g_slist_prepend (remove, iter->data); } for (iter = remove; iter; iter = iter->next) - remove_device (self, NM_DEVICE (iter->data), FALSE); + remove_device (self, NM_DEVICE (iter->data), FALSE, FALSE); g_slist_free (remove); priv->devices = g_slist_append (priv->devices, g_object_ref (device)); @@ -1750,6 +1785,10 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) G_CALLBACK (device_removed_cb), self); + g_signal_connect (device, "notify::" NM_DEVICE_IP_IFACE, + G_CALLBACK (device_ip_iface_changed), + self); + if (priv->startup) { g_signal_connect (device, "notify::" NM_DEVICE_HAS_PENDING_ACTION, G_CALLBACK (device_has_pending_action_changed), @@ -1786,20 +1825,18 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_INTERNAL, sleeping); nm_device_dbus_export (device); + nm_device_finish_init (device); - /* Don't generate a connection e.g. for devices NM just created, or - * for the loopback, or when we're sleeping. */ - if (generate_con && !user_unmanaged && !sleeping) - connection = get_existing_connection (self, device); + if (try_assume) { + connection_assumed = recheck_assume_connection (device, self); + g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME, + G_CALLBACK (recheck_assume_connection), self); + } - /* Start the device if it's supposed to be managed. Note that this will - * manage default-unmanaged devices if they have a generated connection. - */ - if (nm_device_get_managed (device) || connection) { + if (!connection_assumed && nm_device_get_managed (device)) { nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, - connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : - NM_DEVICE_STATE_REASON_NOW_MANAGED); + NM_DEVICE_STATE_REASON_NOW_MANAGED); } nm_settings_device_added (priv->settings, device); @@ -1810,16 +1847,6 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) * need to create new virtual interfaces now. */ system_create_virtual_devices (self); - - /* If the device has a connection it can assume, do that now. If it's a - * device that we might ever want to assume a connection on, then set that up. - */ - if (connection) - assume_connection (self, device, connection); - if (generate_con) { - g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME, - G_CALLBACK (recheck_assume_connection), self); - } } static NMDevice * @@ -1837,27 +1864,14 @@ find_device_by_ip_iface (NMManager *self, const gchar *iface) return NULL; } -static NMDevice * -find_device_by_ifindex (NMManager *self, guint32 ifindex) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; - - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMDevice *candidate = NM_DEVICE (iter->data); - - if (ifindex == nm_device_get_ifindex (candidate)) - return candidate; - } - return NULL; -} +/*******************************************************************/ static void factory_device_added_cb (NMDeviceFactory *factory, NMDevice *device, gpointer user_data) { - add_device (NM_MANAGER (user_data), device, FALSE); + add_device (NM_MANAGER (user_data), device, TRUE); } static gboolean @@ -1877,71 +1891,175 @@ factory_component_added_cb (NMDeviceFactory *factory, #define PLUGIN_PREFIX "libnm-device-plugin-" #define PLUGIN_PATH_TAG "NMManager-plugin-path" -#define PLUGIN_TYPEFUNC_TAG "typefunc" -static void -load_device_factories (NMManager *self) +struct read_device_factory_paths_data { + char *path; + struct stat st; +}; + +static gint +read_device_factory_paths_sort_fcn (gconstpointer a, gconstpointer b) +{ + const struct read_device_factory_paths_data *da = a; + const struct read_device_factory_paths_data *db = b; + time_t ta, tb; + + ta = MAX (da->st.st_mtime, da->st.st_ctime); + tb = MAX (db->st.st_mtime, db->st.st_ctime); + + if (ta < tb) + return 1; + if (ta > tb) + return -1; + return 0; +} + +static char** +read_device_factory_paths (void) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GDir *dir; GError *error = NULL; const char *item; - char *path; - GSList *iter; + GArray *paths; + char **result; + guint i; dir = g_dir_open (NMPLUGINDIR, 0, &error); if (!dir) { - nm_log_warn (LOGD_HW, "Failed to open plugin directory %s: %s", + nm_log_warn (LOGD_HW, "device plugin: failed to open directory %s: %s", NMPLUGINDIR, (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - return; + return NULL; } + paths = g_array_new (FALSE, FALSE, sizeof (struct read_device_factory_paths_data)); + while ((item = g_dir_read_name (dir))) { - GModule *plugin; - NMDeviceFactory *factory; - NMDeviceFactoryCreateFunc create_func; - NMDeviceFactoryDeviceTypeFunc type_func; - NMDeviceType dev_type; - const char *found = NULL; + int errsv; + struct read_device_factory_paths_data data; if (!g_str_has_prefix (item, PLUGIN_PREFIX)) continue; if (g_str_has_suffix (item, ".la")) continue; - path = g_module_build_path (NMPLUGINDIR, item); - g_assert (path); - plugin = g_module_open (path, G_MODULE_BIND_LOCAL); - g_free (path); + data.path = g_build_filename (NMPLUGINDIR, item, NULL); - if (!plugin) { - nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ()); - continue; + if (stat (data.path, &data.st) != 0) { + errsv = errno; + nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (error during stat: %s)", data.path, strerror (errsv)); + goto NEXT; } - - if (!g_module_symbol (plugin, "nm_device_factory_get_device_type", (gpointer) &type_func)) { - nm_log_warn (LOGD_HW, "(%s): failed to find device factory type: %s", item, g_module_error ()); - g_module_close (plugin); - continue; + if (!S_ISREG (data.st.st_mode)) + goto NEXT; + if (data.st.st_uid != 0) { + nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (file must be owned by root)", data.path); + goto NEXT; + } + if (data.st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { + nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (invalid file permissions)", data.path); + goto NEXT; } - /* Make sure we don't double-load plugins */ - dev_type = type_func (); - for (iter = priv->factories; iter; iter = iter->next) { - NMDeviceFactoryDeviceTypeFunc loaded_type_func; + g_array_append_val (paths, data); + continue; +NEXT: + g_free (data.path); + } + g_dir_close (dir); + + /* sort filenames by modification time. */ + g_array_sort (paths, read_device_factory_paths_sort_fcn); + + result = g_new (char *, paths->len + 1); + for (i = 0; i < paths->len; i++) + result[i] = g_array_index (paths, struct read_device_factory_paths_data, i).path; + result[i] = NULL; - loaded_type_func = g_object_get_data (G_OBJECT (iter->data), PLUGIN_TYPEFUNC_TAG); - if (dev_type == loaded_type_func ()) { - found = g_object_get_data (G_OBJECT (iter->data), PLUGIN_PATH_TAG); - break; + g_array_free (paths, TRUE); + return result; +} + +static gboolean +_register_device_factory (NMManager *self, + NMDeviceFactory *factory, + gboolean duplicate_check, + const char *path, + GError **error) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMDeviceType ftype; + GSList *iter; + + if (duplicate_check) { + /* Make sure we don't double-register factories */ + ftype = nm_device_factory_get_device_type (factory); + for (iter = priv->factories; iter; iter = iter->next) { + if (ftype == nm_device_factory_get_device_type (iter->data)) { + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, + "multiple plugins for same type (using '%s' instead of '%s')", + (char *) g_object_get_data (G_OBJECT (iter->data), PLUGIN_PATH_TAG), + path); + return FALSE; } } - if (found) { - nm_log_warn (LOGD_HW, "Found multiple device plugins for same type: %s vs %s", - found, g_module_name (plugin)); - g_module_close (plugin); + } + + priv->factories = g_slist_append (priv->factories, factory); + + g_signal_connect (factory, + NM_DEVICE_FACTORY_DEVICE_ADDED, + G_CALLBACK (factory_device_added_cb), + self); + g_signal_connect (factory, + NM_DEVICE_FACTORY_COMPONENT_ADDED, + G_CALLBACK (factory_component_added_cb), + self); + g_object_set_data_full (G_OBJECT (factory), PLUGIN_PATH_TAG, + g_strdup (path), g_free); + return TRUE; +} + +static void +load_device_factories (NMManager *self) +{ + NMDeviceFactory *factory; + const GSList *iter; + GError *error = NULL; + char **path, **paths; + + /* Register internal factories first */ + for (iter = nm_device_factory_get_internal_factory_types (); iter; iter = iter->next) { + GType ftype = (GType) GPOINTER_TO_SIZE (iter->data); + + factory = (NMDeviceFactory *) g_object_new (ftype, NULL); + g_assert (factory); + if (_register_device_factory (self, factory, FALSE, "internal", &error)) { + nm_log_dbg (LOGD_HW, "Loaded device plugin: %s", g_type_name (ftype)); + } else { + nm_log_warn (LOGD_HW, "Loading device plugin failed: %s", error->message); + g_object_unref (factory); + g_clear_error (&error); + } + } + + paths = read_device_factory_paths (); + if (!paths) + return; + + for (path = paths; *path; path++) { + GModule *plugin; + NMDeviceFactoryCreateFunc create_func; + const char *item; + + item = strrchr (*path, '/'); + g_assert (item); + + plugin = g_module_open (*path, G_MODULE_BIND_LOCAL); + + if (!plugin) { + nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ()); continue; } @@ -1961,28 +2079,21 @@ load_device_factories (NMManager *self) } g_clear_error (&error); - g_module_make_resident (plugin); - priv->factories = g_slist_prepend (priv->factories, factory); - - g_signal_connect (factory, - NM_DEVICE_FACTORY_DEVICE_ADDED, - G_CALLBACK (factory_device_added_cb), - self); - g_signal_connect (factory, - NM_DEVICE_FACTORY_COMPONENT_ADDED, - G_CALLBACK (factory_component_added_cb), - self); - g_object_set_data_full (G_OBJECT (factory), PLUGIN_PATH_TAG, - g_strdup (g_module_name (plugin)), g_free); - g_object_set_data (G_OBJECT (factory), PLUGIN_TYPEFUNC_TAG, type_func); - - nm_log_info (LOGD_HW, "Loaded device plugin: %s", g_module_name (plugin)); - }; - g_dir_close (dir); - - priv->factories = g_slist_reverse (priv->factories); + if (_register_device_factory (self, factory, TRUE, g_module_name (plugin), &error)) { + nm_log_info (LOGD_HW, "Loaded device plugin: %s", g_module_name (plugin)); + g_module_make_resident (plugin); + } else { + nm_log_warn (LOGD_HW, "Loading device plugin failed: %s", error->message); + g_object_unref (factory); + g_module_close (plugin); + g_clear_error (&error); + } + } + g_strfreev (paths); } +/*******************************************************************/ + static void platform_link_added (NMManager *self, int ifindex, @@ -1999,7 +2110,7 @@ platform_link_added (NMManager *self, if (priv->ignore_link_added_cb > 0) return; - if (find_device_by_ifindex (self, ifindex)) + if (nm_manager_get_device_by_ifindex (self, ifindex)) return; /* Try registered device factories */ @@ -2029,60 +2140,7 @@ platform_link_added (NMManager *self, return; if (device == NULL) { - int parent_ifindex = -1; - NMDevice *parent; - switch (plink->type) { - case NM_LINK_TYPE_ETHERNET: - device = nm_device_ethernet_new (plink); - break; - case NM_LINK_TYPE_INFINIBAND: - device = nm_device_infiniband_new (plink); - break; - case NM_LINK_TYPE_BOND: - device = nm_device_bond_new (plink); - break; - case NM_LINK_TYPE_TEAM: - device = nm_device_team_new (plink); - break; - case NM_LINK_TYPE_BRIDGE: - device = nm_device_bridge_new (plink); - break; - case NM_LINK_TYPE_VLAN: - /* Have to find the parent device */ - if (nm_platform_vlan_get_info (ifindex, &parent_ifindex, NULL)) { - parent = find_device_by_ifindex (self, parent_ifindex); - if (parent) - device = nm_device_vlan_new (plink, parent); - else { - /* If udev signaled the VLAN interface before it signaled - * the VLAN's parent at startup we may not know about the - * parent device yet. But we'll find it on the second pass - * from nm_manager_start(). - */ - nm_log_dbg (LOGD_HW, "(%s): VLAN parent interface unknown", plink->name); - } - } else - nm_log_err (LOGD_HW, "(%s): failed to get VLAN parent ifindex", plink->name); - break; - case NM_LINK_TYPE_VETH: - device = nm_device_veth_new (plink); - break; - case NM_LINK_TYPE_TUN: - case NM_LINK_TYPE_TAP: - device = nm_device_tun_new (plink); - break; - case NM_LINK_TYPE_MACVLAN: - case NM_LINK_TYPE_MACVTAP: - device = nm_device_macvlan_new (plink); - break; - case NM_LINK_TYPE_VXLAN: - device = nm_device_vxlan_new (plink); - break; - case NM_LINK_TYPE_GRE: - case NM_LINK_TYPE_GRETAP: - device = nm_device_gre_new (plink); - break; case NM_LINK_TYPE_WWAN_ETHERNET: /* WWAN pseudo-ethernet interfaces are handled automatically by @@ -2091,6 +2149,7 @@ platform_link_added (NMManager *self, break; case NM_LINK_TYPE_OLPC_MESH: + case NM_LINK_TYPE_TEAM: case NM_LINK_TYPE_WIFI: case NM_LINK_TYPE_WIMAX: nm_log_info (LOGD_HW, "(%s): '%s' plugin not available; creating generic device", @@ -2124,9 +2183,9 @@ platform_link_cb (NMPlatform *platform, NMManager *self = NM_MANAGER (user_data); NMDevice *device; - device = find_device_by_ifindex (self, ifindex); + device = nm_manager_get_device_by_ifindex (self, ifindex); if (device) - remove_device (self, device, FALSE); + remove_device (self, device, FALSE, TRUE); break; } default: @@ -2314,7 +2373,7 @@ find_master (NMManager *self, NMConnection *candidate = iter->data; char *vname; - if (connection_needs_virtual_device (candidate)) { + if (nm_connection_is_virtual (candidate)) { vname = get_virtual_iface_name (self, candidate, NULL); if ( g_strcmp0 (master, vname) == 0 && is_compatible_with_slave (candidate, connection)) @@ -2458,7 +2517,7 @@ ensure_master_active_connection (NMManager *self, /* Otherwise, the device is unmanaged, unavailable, or disconnecting */ g_set_error (error, NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNMANAGED_DEVICE, + NM_MANAGER_ERROR_DEPENDENCY_FAILED, "Master device %s unmanaged or not available for activation", nm_device_get_iface (master_device)); } else if (master_connection) { @@ -2495,7 +2554,7 @@ ensure_master_active_connection (NMManager *self, /* Device described by master_connection may be a virtual one that's * not created yet. */ - if (!found_device && connection_needs_virtual_device (master_connection)) { + if (!found_device && nm_connection_is_virtual (master_connection)) { master_ac = nm_manager_activate_connection (self, master_connection, NULL, @@ -2554,7 +2613,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * device = nm_active_connection_get_device (active); if (!device) { - if (!connection_needs_virtual_device (connection)) { + if (!nm_connection_is_virtual (connection)) { NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -2606,10 +2665,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * existing_connection = nm_device_get_connection (device); subject = nm_active_connection_get_subject (active); if (existing_connection && - !nm_auth_uid_in_acl (existing_connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + !nm_auth_is_subject_in_acl (existing_connection, + nm_session_monitor_get (), + subject, + &error_desc)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -2633,7 +2692,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * */ if (!nm_active_connection_get_user_requested (active) && !nm_device_autoconnect_allowed (device)) { - g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED, + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, "%s does not allow automatic connections at this time", nm_device_get_iface (device)); return FALSE; @@ -2898,10 +2957,10 @@ nm_manager_activate_connection (NMManager *self, g_return_val_if_fail (*error == NULL, NULL); /* Ensure the subject has permissions for this connection */ - if (!nm_auth_uid_in_acl (connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (connection, + nm_session_monitor_get (), + subject, + &error_desc)) { g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -2942,7 +3001,7 @@ validate_activation_request (NMManager *self, g_assert (out_vpn); /* Validate the caller */ - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { g_set_error_literal (error, NM_MANAGER_ERROR, @@ -2952,10 +3011,10 @@ validate_activation_request (NMManager *self, } /* Ensure the subject has permissions for this connection */ - if (!nm_auth_uid_in_acl (connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (connection, + nm_session_monitor_get (), + subject, + &error_desc)) { g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -2984,7 +3043,7 @@ validate_activation_request (NMManager *self, goto error; } } else { - gboolean is_software = connection_needs_virtual_device (connection); + gboolean is_software = nm_connection_is_virtual (connection); /* VPN and software-device connections don't need a device yet */ if (!vpn && !is_software) { @@ -3272,9 +3331,13 @@ impl_manager_add_and_activate_connection (NMManager *self, * specific data being in the connection till then (especially in * validate_activation_request()). */ - connection = nm_connection_new (); - if (settings && g_hash_table_size (settings)) - nm_connection_replace_settings (connection, settings, NULL); + connection = nm_simple_connection_new (); + if (settings && g_hash_table_size (settings)) { + GVariant *settings_dict = nm_utils_connection_hash_to_dict (settings); + + nm_connection_replace_settings (connection, settings_dict, NULL); + g_variant_unref (settings_dict); + } subject = validate_activation_request (self, context, @@ -3298,16 +3361,18 @@ impl_manager_add_and_activate_connection (NMManager *self, if (vpn) { /* Try to fill the VPN's connection setting and name at least */ if (!nm_connection_get_setting_vpn (connection)) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, + error = g_error_new_literal (NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, "VPN connections require a 'vpn' setting"); + g_prefix_error (&error, "%s: ", NM_SETTING_VPN_SETTING_NAME); goto error; } nm_utils_complete_generic (connection, NM_SETTING_VPN_SETTING_NAME, all_connections, - _("VPN connection %d"), + NULL, + _("VPN connection"), NULL, FALSE); /* No IPv6 by default for now */ } else { @@ -3368,7 +3433,7 @@ nm_manager_deactivate_connection (NMManager *manager, } if (NM_IS_VPN_CONNECTION (active)) { - NMVPNConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED; + NMVpnConnectionStateReason vpn_reason = NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED; if (reason == NM_DEVICE_STATE_REASON_CONNECTION_REMOVED) vpn_reason = NM_VPN_CONNECTION_STATE_REASON_CONNECTION_REMOVED; @@ -3467,7 +3532,7 @@ impl_manager_deactivate_connection (NMManager *self, } /* Validate the caller */ - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -3476,10 +3541,10 @@ impl_manager_deactivate_connection (NMManager *self, } /* Ensure the subject has permissions for this connection */ - if (!nm_auth_uid_in_acl (connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (connection, + nm_session_monitor_get (), + subject, + &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); @@ -3965,13 +4030,8 @@ impl_manager_set_logging (NMManager *manager, } if (nm_logging_setup (level, domains, NULL, &error)) { - char *new_level = nm_logging_level_to_string (); - char *new_domains = nm_logging_domains_to_string (); - nm_log_info (LOGD_CORE, "logging: level '%s' domains '%s'", - new_level, new_domains); - g_free (new_level); - g_free (new_domains); + nm_logging_level_to_string (), nm_logging_domains_to_string ()); } done: @@ -3987,8 +4047,8 @@ impl_manager_get_logging (NMManager *manager, char **level, char **domains) { - *level = nm_logging_level_to_string (); - *domains = nm_logging_domains_to_string (); + *level = g_strdup (nm_logging_level_to_string ()); + *domains = g_strdup (nm_logging_domains_to_string ()); } static void @@ -4075,6 +4135,7 @@ void nm_manager_start (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; guint i; /* Set initial radio enabled/disabled state */ @@ -4105,6 +4166,10 @@ nm_manager_start (NMManager *self) system_unmanaged_devices_changed_cb (priv->settings, NULL, self); system_hostname_changed_cb (priv->settings, NULL, self); + /* Start device factories */ + for (iter = priv->factories; iter; iter = iter->next) + nm_device_factory_start (iter->data); + nm_platform_query_devices (); /* @@ -4116,6 +4181,16 @@ nm_manager_start (NMManager *self) check_if_startup_complete (self); } +void +nm_manager_stop (NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + + /* Remove all devices */ + while (priv->devices) + remove_device (self, NM_DEVICE (priv->devices->data), TRUE, TRUE); +} + static gboolean handle_firmware_changed (gpointer user_data) { @@ -4218,6 +4293,7 @@ policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user priv->primary_connection = ac ? g_object_ref (ac) : NULL; nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_id (ac) : "(none)"); g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION); + g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE); } } @@ -4373,7 +4449,7 @@ prop_filter (DBusConnection *connection, goto out; } - subject = nm_auth_subject_new_from_message (connection, message); + subject = nm_auth_subject_new_unix_process_from_message (connection, message); if (!subject) { reply = dbus_message_new_error (message, NM_PERM_DENIED_ERROR, "Could not determine request UID."); @@ -4408,7 +4484,7 @@ out: } static void -authority_changed_cb (gpointer user_data) +authority_changed_cb (NMAuthManager *auth_manager, gpointer user_data) { /* Let clients know they should re-check their authorization */ g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); @@ -4613,7 +4689,7 @@ nm_manager_new (NMSettings *settings, bus = nm_dbus_manager_get_connection (priv->dbus_mgr); if (!bus) { - g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INTERNAL, + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "Failed to initialize D-Bus connection"); g_object_unref (singleton); return NULL; @@ -4637,7 +4713,7 @@ nm_manager_new (NMSettings *settings, G_CALLBACK (connectivity_changed), singleton); if (!dbus_connection_add_filter (dbus_connection, prop_filter, singleton, NULL)) { - g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INTERNAL, + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "Failed to register DBus connection filter"); g_object_unref (singleton); return NULL; @@ -4773,7 +4849,11 @@ nm_manager_init (NMManager *manager) G_CALLBACK (resuming_cb), manager); /* Listen for authorization changes */ - nm_auth_changed_func_register (authority_changed_cb, manager); + g_signal_connect (nm_auth_manager_get (), + NM_AUTH_MANAGER_SIGNAL_CHANGED, + G_CALLBACK (authority_changed_cb), + manager); + /* Monitor the firmware directory */ if (strlen (KERNEL_FIRMWARE_DIR)) { @@ -4806,6 +4886,7 @@ get_property (GObject *object, guint prop_id, GSList *iter; GPtrArray *array; const char *path; + const char *type; switch (prop_id) { case PROP_VERSION: @@ -4855,6 +4936,10 @@ get_property (GObject *object, guint prop_id, path = priv->primary_connection ? nm_active_connection_get_path (priv->primary_connection) : NULL; g_value_set_boxed (value, path ? path : "/"); break; + case PROP_PRIMARY_CONNECTION_TYPE: + type = priv->primary_connection ? nm_active_connection_get_connection_type (priv->primary_connection) : NULL; + g_value_set_string (value, type ? type : ""); + break; case PROP_ACTIVATING_CONNECTION: path = priv->activating_connection ? nm_active_connection_get_path (priv->activating_connection) : NULL; g_value_set_boxed (value, path ? path : "/"); @@ -4925,11 +5010,11 @@ dispose (GObject *object) g_slist_free_full (priv->auth_chains, (GDestroyNotify) nm_auth_chain_unref); priv->auth_chains = NULL; - nm_auth_changed_func_unregister (authority_changed_cb, manager); + g_signal_handlers_disconnect_by_func (nm_auth_manager_get (), + G_CALLBACK (authority_changed_cb), + manager); - /* Remove all devices */ - while (priv->devices) - remove_device (manager, NM_DEVICE (priv->devices->data), TRUE); + g_assert (priv->devices == NULL); if (priv->ac_cleanup_id) { g_source_remove (priv->ac_cleanup_id); @@ -5015,141 +5100,132 @@ nm_manager_class_init (NMManagerClass *manager_class) /* properties */ g_object_class_install_property (object_class, PROP_VERSION, - g_param_spec_string (NM_MANAGER_VERSION, - "Version", - "NetworkManager version", + g_param_spec_string (NM_MANAGER_VERSION, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint (NM_MANAGER_STATE, - "State", - "Current state", + g_param_spec_uint (NM_MANAGER_STATE, "", "", 0, NM_STATE_DISCONNECTED, 0, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_STARTUP, - g_param_spec_boolean (NM_MANAGER_STARTUP, - "Startup", - "Is NetworkManager still starting up", + g_param_spec_boolean (NM_MANAGER_STARTUP, "", "", TRUE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_NETWORKING_ENABLED, - g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, - "NetworkingEnabled", - "Is networking enabled", + g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "", TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WIRELESS_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, - "WirelessEnabled", - "Is wireless enabled", + g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WIRELESS_HARDWARE_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, - "WirelessHardwareEnabled", - "RF kill state", + g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "", TRUE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WWAN_ENABLED, - g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, - "WwanEnabled", - "Is mobile broadband enabled", + g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WWAN_HARDWARE_ENABLED, - g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, - "WwanHardwareEnabled", - "Whether WWAN is disabled by a hardware switch or not", + g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "", TRUE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WIMAX_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, - "WimaxEnabled", - "Is WiMAX enabled", + g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_WIMAX_HARDWARE_ENABLED, - g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, - "WimaxHardwareEnabled", - "Whether WiMAX is disabled by a hardware switch or not", + g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "", TRUE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTIONS, - g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, - "Active connections", - "Active connections", + g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONNECTIVITY, - g_param_spec_uint (NM_MANAGER_CONNECTIVITY, - "Connectivity", - "Connectivity state", + g_param_spec_uint (NM_MANAGER_CONNECTIVITY, "", "", NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PRIMARY_CONNECTION, - g_param_spec_boxed (NM_MANAGER_PRIMARY_CONNECTION, - "Primary connection", - "Primary connection", + g_param_spec_boxed (NM_MANAGER_PRIMARY_CONNECTION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_PRIMARY_CONNECTION_TYPE, + g_param_spec_string (NM_MANAGER_PRIMARY_CONNECTION_TYPE, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_ACTIVATING_CONNECTION, - g_param_spec_boxed (NM_MANAGER_ACTIVATING_CONNECTION, - "Activating connection", - "Activating connection", + g_param_spec_boxed (NM_MANAGER_ACTIVATING_CONNECTION, "", "", DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Hostname is not exported over D-Bus */ g_object_class_install_property (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_MANAGER_HOSTNAME, - "Hostname", - "Hostname", + g_param_spec_string (NM_MANAGER_HOSTNAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Sleeping is not exported over D-Bus */ g_object_class_install_property (object_class, PROP_SLEEPING, - g_param_spec_boolean (NM_MANAGER_SLEEPING, - "Sleeping", - "Sleeping", + g_param_spec_boolean (NM_MANAGER_SLEEPING, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEVICES, - g_param_spec_boxed (NM_MANAGER_DEVICES, - "Devices", - "Devices", + g_param_spec_boxed (NM_MANAGER_DEVICES, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[DEVICE_ADDED] = @@ -5204,11 +5280,17 @@ nm_manager_class_init (NMManagerClass *manager_class) 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[CONFIGURE_QUIT] = + g_signal_new (NM_MANAGER_CONFIGURE_QUIT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (manager_class), &dbus_glib_nm_manager_object_info); - dbus_g_error_domain_register (NM_MANAGER_ERROR, NULL, NM_TYPE_MANAGER_ERROR); - dbus_g_error_domain_register (NM_LOGGING_ERROR, "org.freedesktop.NetworkManager.Logging", NM_TYPE_LOGGING_ERROR); + dbus_g_error_domain_register (NM_MANAGER_ERROR, NM_DBUS_INTERFACE, NM_TYPE_MANAGER_ERROR); } diff --git a/src/nm-manager.h b/src/nm-manager.h index 81eefc7b..3b00e805 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -19,15 +19,14 @@ * Copyright (C) 2007 - 2010 Red Hat, Inc. */ -#ifndef NM_MANAGER_H -#define NM_MANAGER_H +#ifndef __NETWORKMANAGER_MANAGER_H__ +#define __NETWORKMANAGER_MANAGER_H__ #include #include -#include -#include "nm-device.h" -#include "nm-settings.h" -#include "nm-auth-subject.h" + +#include "nm-types.h" +#include "nm-connection.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -36,22 +35,6 @@ #define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MANAGER)) #define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass)) -typedef enum { - NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, /*< nick=UnknownConnection >*/ - NM_MANAGER_ERROR_UNKNOWN_DEVICE, /*< nick=UnknownDevice >*/ - NM_MANAGER_ERROR_UNMANAGED_DEVICE, /*< nick=UnmanagedDevice >*/ - NM_MANAGER_ERROR_SYSTEM_CONNECTION, /*< nick=SystemConnection >*/ - NM_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ - NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, /*< nick=ConnectionNotActive >*/ - NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, /*< nick=AlreadyAsleepOrAwake >*/ - NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, /*< nick=AlreadyEnabledOrDisabled >*/ - NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, /*< nick=UnsupportedConnectionType >*/ - NM_MANAGER_ERROR_DEPENDENCY_FAILED, /*< nick=DependencyFailed >*/ - NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED, /*< nick=AutoconnectNotAllowed >*/ - NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, /*< nick=ConnectionAlreadyActive >*/ - NM_MANAGER_ERROR_INTERNAL, /*< nick=Internal >*/ -} NMManagerError; - #define NM_MANAGER_VERSION "version" #define NM_MANAGER_STATE "state" #define NM_MANAGER_STARTUP "startup" @@ -65,6 +48,7 @@ typedef enum { #define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections" #define NM_MANAGER_CONNECTIVITY "connectivity" #define NM_MANAGER_PRIMARY_CONNECTION "primary-connection" +#define NM_MANAGER_PRIMARY_CONNECTION_TYPE "primary-connection-type" #define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection" #define NM_MANAGER_DEVICES "devices" @@ -75,11 +59,12 @@ typedef enum { /* Internal signals */ #define NM_MANAGER_ACTIVE_CONNECTION_ADDED "active-connection-added" #define NM_MANAGER_ACTIVE_CONNECTION_REMOVED "active-connection-removed" +#define NM_MANAGER_CONFIGURE_QUIT "configure-quit" -typedef struct { +struct _NMManager { GObject parent; -} NMManager; +}; typedef struct { GObjectClass parent; @@ -93,45 +78,39 @@ typedef struct { GType nm_manager_get_type (void); /* nm_manager_new() should only be used by main.c */ -NMManager *nm_manager_new (NMSettings *settings, - const char *state_file, - gboolean initial_net_enabled, - gboolean initial_wifi_enabled, - gboolean initial_wwan_enabled, - gboolean initial_wimax_enabled, - GError **error); - -NMManager *nm_manager_get (void); - -void nm_manager_start (NMManager *manager); - -const GSList *nm_manager_get_active_connections (NMManager *manager); -GSList *nm_manager_get_activatable_connections (NMManager *manager); +NMManager * nm_manager_new (NMSettings *settings, + const char *state_file, + gboolean initial_net_enabled, + gboolean initial_wifi_enabled, + gboolean initial_wwan_enabled, + gboolean initial_wimax_enabled, + GError **error); + +NMManager * nm_manager_get (void); + +void nm_manager_start (NMManager *manager); +void nm_manager_stop (NMManager *manager); +NMState nm_manager_get_state (NMManager *manager); +const GSList *nm_manager_get_active_connections (NMManager *manager); +GSList * nm_manager_get_activatable_connections (NMManager *manager); /* Device handling */ -const GSList *nm_manager_get_devices (NMManager *manager); - -NMDevice *nm_manager_get_device_by_master (NMManager *manager, - const char *master, - const char *driver); -NMDevice *nm_manager_get_device_by_ifindex (NMManager *manager, - int ifindex); - -NMActiveConnection *nm_manager_activate_connection (NMManager *manager, - NMConnection *connection, - const char *specific_object, - NMDevice *device, - NMAuthSubject *subject, - GError **error); +const GSList * nm_manager_get_devices (NMManager *manager); -gboolean nm_manager_deactivate_connection (NMManager *manager, - const char *connection_path, - NMDeviceStateReason reason, - GError **error); +NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager, + int ifindex); -/* State handling */ +NMActiveConnection *nm_manager_activate_connection (NMManager *manager, + NMConnection *connection, + const char *specific_object, + NMDevice *device, + NMAuthSubject *subject, + GError **error); -NMState nm_manager_get_state (NMManager *manager); +gboolean nm_manager_deactivate_connection (NMManager *manager, + const char *connection_path, + NMDeviceStateReason reason, + GError **error); -#endif /* NM_MANAGER_H */ +#endif /* __NETWORKMANAGER_MANAGER_H__ */ diff --git a/src/nm-policy.c b/src/nm-policy.c index d46aca04..87fcdcc9 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -19,7 +19,8 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -32,17 +33,24 @@ #include "nm-activation-request.h" #include "nm-logging.h" #include "nm-device.h" +#include "nm-default-route-manager.h" #include "nm-dbus-manager.h" #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" #include "nm-platform.h" #include "nm-dns-manager.h" #include "nm-vpn-manager.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-firewall-manager.h" #include "nm-dispatcher.h" #include "nm-utils.h" +#include "nm-core-internal.h" #include "nm-glib-compat.h" +#include "nm-manager.h" +#include "nm-settings.h" +#include "nm-settings-connection.h" +#include "nm-dhcp4-config.h" +#include "nm-dhcp6-config.h" typedef struct { NMManager *manager; @@ -54,7 +62,6 @@ typedef struct { GSList *pending_secondaries; - NMFirewallManager *fw_manager; gulong fw_started_id; NMSettings *settings; @@ -95,164 +102,22 @@ static NMDevice * get_best_ip4_device (NMPolicy *self, gboolean fully_activated) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const GSList *iter; - NMDevice *best = NULL; - int best_prio = G_MAXINT; - - for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) { - NMDevice *dev = NM_DEVICE (iter->data); - NMDeviceType devtype = nm_device_get_device_type (dev); - NMDeviceState state = nm_device_get_state (dev); - NMActRequest *req; - NMConnection *connection; - NMSettingIP4Config *s_ip4; - int prio; - const char *method = NULL; - - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state >= NM_DEVICE_STATE_DEACTIVATING) - continue; - - if (fully_activated && state < NM_DEVICE_STATE_SECONDARIES) - continue; - - if (fully_activated) { - NMIP4Config *ip4_config; - - ip4_config = nm_device_get_ip4_config (dev); - if (!ip4_config) - continue; - - /* Make sure the device has a gateway */ - if (!nm_ip4_config_get_gateway (ip4_config) && (devtype != NM_DEVICE_TYPE_MODEM)) - continue; - - /* 'never-default' devices can't ever be the default */ - if (nm_ip4_config_get_never_default (ip4_config)) - continue; - } - - req = nm_device_get_act_request (dev); - g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - /* If IPv4 is disabled or link-local-only, it can't be the default */ - if ( !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) - || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) - continue; - - /* 'never-default' devices can't ever be the default */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_assert (s_ip4); - if (nm_setting_ip4_config_get_never_default (s_ip4)) - continue; - - prio = nm_device_get_priority (dev); - if ( prio < best_prio - || (priv->default_device4 == dev && prio == best_prio) - || !best) { - best = dev; - best_prio = prio; - } - } - - if (!best) - return NULL; - - if (!fully_activated) { - NMDeviceState state = nm_device_get_state (best); - - /* There's only a best activating device if the best device - * among all activating and already-activated devices is a - * still-activating one. - */ - if (state >= NM_DEVICE_STATE_SECONDARIES) - return NULL; - } - - return best; + return nm_default_route_manager_ip4_get_best_device (nm_default_route_manager_get (), + nm_manager_get_devices (priv->manager), + fully_activated, + priv->default_device4); } static NMDevice * get_best_ip6_device (NMPolicy *self, gboolean fully_activated) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const GSList *iter; - NMDevice *best = NULL; - int best_prio = G_MAXINT; - - for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) { - NMDevice *dev = NM_DEVICE (iter->data); - NMDeviceType devtype = nm_device_get_device_type (dev); - NMDeviceState state = nm_device_get_state (dev); - NMActRequest *req; - NMConnection *connection; - NMSettingIP6Config *s_ip6; - int prio; - const char *method = NULL; - - if ( state <= NM_DEVICE_STATE_DISCONNECTED - || state >= NM_DEVICE_STATE_DEACTIVATING) - continue; - if (fully_activated && state < NM_DEVICE_STATE_SECONDARIES) - continue; - - if (fully_activated) { - NMIP6Config *ip6_config; - - ip6_config = nm_device_get_ip6_config (dev); - if (!ip6_config) - continue; - - if (!nm_ip6_config_get_gateway (ip6_config) && (devtype != NM_DEVICE_TYPE_MODEM)) - continue; - - if (nm_ip6_config_get_never_default (ip6_config)) - continue; - } - - req = nm_device_get_act_request (dev); - g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) - || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) - continue; - - s_ip6 = nm_connection_get_setting_ip6_config (connection); - g_assert (s_ip6); - if (nm_setting_ip6_config_get_never_default (s_ip6)) - continue; - - prio = nm_device_get_priority (dev); - if ( prio < best_prio - || (priv->default_device6 == dev && prio == best_prio) - || !best) { - best = dev; - best_prio = prio; - } - } - - if (!best) - return NULL; - - if (!fully_activated) { - NMDeviceState state = nm_device_get_state (best); - - /* There's only a best activating device if the best device - * among all activating and already-activated devices is an - * activating one. - */ - if (state >= NM_DEVICE_STATE_SECONDARIES) - return NULL; - } - - return best; + return nm_default_route_manager_ip6_get_best_device (nm_default_route_manager_get (), + nm_manager_get_devices (priv->manager), + fully_activated, + priv->default_device6); } #define FALLBACK_HOSTNAME4 "localhost.localdomain" @@ -389,11 +254,12 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) /* Try a persistent hostname first */ g_object_get (G_OBJECT (priv->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL); - if (configured_hostname) { + if (configured_hostname && nm_utils_is_specific_hostname (configured_hostname)) { _set_hostname (policy, configured_hostname, "from system configuration"); g_free (configured_hostname); return; } + g_free (configured_hostname); /* Try automatically determined hostname from the best device's IP config */ if (!best4) @@ -410,7 +276,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) } if (best4) { - NMDHCP4Config *dhcp4_config; + NMDhcp4Config *dhcp4_config; /* Grab a hostname out of the device's DHCP4 config */ dhcp4_config = nm_device_get_dhcp4_config (best4); @@ -429,7 +295,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) } } } else if (best6) { - NMDHCP6Config *dhcp6_config; + NMDhcp6Config *dhcp6_config; /* Grab a hostname out of the device's DHCP6 config */ dhcp6_config = nm_device_get_dhcp6_config (best6); @@ -467,12 +333,14 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) const NMPlatformIP4Address *addr4; addr4 = nm_ip4_config_get_address (ip4_config, 0); + g_clear_object (&priv->lookup_addr); priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr4->address, G_SOCKET_FAMILY_IPV4); } else if (ip6_config && nm_ip6_config_get_num_addresses (ip6_config) > 0) { const NMPlatformIP6Address *addr6; addr6 = nm_ip6_config_get_address (ip6_config, 0); + g_clear_object (&priv->lookup_addr); priv->lookup_addr = g_inet_address_new_from_bytes ((guint8 *) &addr6->address, G_SOCKET_FAMILY_IPV6); } else { @@ -512,90 +380,19 @@ update_default_ac (NMPolicy *policy, } static NMIP4Config * -get_best_ip4_config (NMPolicy *policy, +get_best_ip4_config (NMPolicy *self, gboolean ignore_never_default, const char **out_ip_iface, - int *out_ip_ifindex, NMActiveConnection **out_ac, NMDevice **out_device, - NMVPNConnection **out_vpn) + NMVpnConnection **out_vpn) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - const GSList *connections, *iter; - NMDevice *device; - NMActRequest *req = NULL; - NMIP4Config *ip4_config = NULL; - - /* If a VPN connection is active, it is preferred */ - connections = nm_manager_get_active_connections (priv->manager); - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data); - NMVPNConnection *candidate; - NMIP4Config *vpn_ip4; - NMConnection *tmp; - NMSettingIP4Config *s_ip4; - NMVPNConnectionState vpn_state; - - if (!NM_IS_VPN_CONNECTION (active)) - continue; - - candidate = NM_VPN_CONNECTION (active); - - tmp = nm_active_connection_get_connection (active); - g_assert (tmp); - - vpn_state = nm_vpn_connection_get_vpn_state (candidate); - if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED) - continue; - - vpn_ip4 = nm_vpn_connection_get_ip4_config (candidate); - if (!vpn_ip4) - continue; - - if (ignore_never_default == FALSE) { - /* Check for a VPN-provided config never-default */ - if (nm_ip4_config_get_never_default (vpn_ip4)) - continue; - - /* Check the user's preference from the NMConnection */ - s_ip4 = nm_connection_get_setting_ip4_config (tmp); - if (nm_setting_ip4_config_get_never_default (s_ip4)) - continue; - } - - ip4_config = vpn_ip4; - if (out_vpn) - *out_vpn = candidate; - if (out_ac) - *out_ac = active; - if (out_ip_iface) - *out_ip_iface = nm_vpn_connection_get_ip_iface (candidate); - if (out_ip_ifindex) - *out_ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate); - break; - } - - /* If no VPN connections, we use the best device instead */ - if (!ip4_config) { - device = get_best_ip4_device (policy, TRUE); - if (device) { - ip4_config = nm_device_get_ip4_config (device); - g_assert (ip4_config); - req = nm_device_get_act_request (device); - g_assert (req); - - if (out_device) - *out_device = device; - if (out_ac) - *out_ac = NM_ACTIVE_CONNECTION (req); - if (out_ip_iface) - *out_ip_iface = nm_device_get_ip_iface (device); - if (out_ip_ifindex) - *out_ip_ifindex = nm_device_get_ip_ifindex (device); - } - } - - return ip4_config; + return nm_default_route_manager_ip4_get_best_config (nm_default_route_manager_get (), + ignore_never_default, + out_ip_iface, + out_ac, + out_device, + out_vpn); } static void @@ -603,10 +400,10 @@ update_ip4_dns (NMPolicy *policy, NMDnsManager *dns_mgr) { NMIP4Config *ip4_config; const char *ip_iface = NULL; - NMVPNConnection *vpn = NULL; + NMVpnConnection *vpn = NULL; NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; - ip4_config = get_best_ip4_config (policy, TRUE, &ip_iface, NULL, NULL, NULL, &vpn); + ip4_config = get_best_ip4_config (policy, TRUE, &ip_iface, NULL, NULL, &vpn); if (ip4_config) { if (vpn) dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; @@ -624,18 +421,14 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMDevice *best = NULL, *default_device; NMConnection *connection = NULL; - NMVPNConnection *vpn = NULL; + NMVpnConnection *vpn = NULL; NMActiveConnection *best_ac = NULL; - NMIP4Config *ip4_config = NULL; const char *ip_iface = NULL; - int ip_ifindex = -1; - guint32 gw_addr = 0; /* Note that we might have an IPv4 VPN tunneled over an IPv6-only device, * so we can get (vpn != NULL && best == NULL). */ - ip4_config = get_best_ip4_config (policy, FALSE, &ip_iface, &ip_ifindex, &best_ac, &best, &vpn); - if (!ip4_config) { + if (!get_best_ip4_config (policy, FALSE, &ip_iface, &best_ac, &best, &vpn)) { gboolean changed; changed = (priv->default_device4 != NULL); @@ -650,52 +443,24 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) if (!force_update && best && (best == priv->default_device4)) return; - gw_addr = nm_ip4_config_get_gateway (ip4_config); - - if (vpn) { - NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - int parent_ifindex = nm_device_get_ip_ifindex (parent); - NMIP4Config *parent_ip4 = nm_device_get_ip4_config (parent); - guint32 parent_mss = parent_ip4 ? nm_ip4_config_get_mss (parent_ip4) : 0; - in_addr_t int_gw = nm_vpn_connection_get_ip4_internal_gateway (vpn); - int mss = nm_ip4_config_get_mss (ip4_config); - - /* If no VPN interface, use the parent interface */ - if (ip_ifindex <= 0) - ip_ifindex = parent_ifindex; - - if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, - 0, 0, int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip4_route_add (parent_ifindex, NM_PLATFORM_SOURCE_VPN, - gw_addr, 32, 0, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, - 0, 0, int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) - nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set default route."); - } + if (best) { + const GSList *connections, *iter; - default_device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - } else { - int mss = nm_ip4_config_get_mss (ip4_config); - - g_assert (ip_iface); - if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - 0, 0, gw_addr, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - gw_addr, 32, 0, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); - if (!nm_platform_ip4_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - 0, 0, gw_addr, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - nm_log_err (LOGD_IP4, "Failed to set default route."); - } + connections = nm_manager_get_active_connections (priv->manager); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMActiveConnection *active = iter->data; + + if ( NM_IS_VPN_CONNECTION (active) + && nm_vpn_connection_get_ip4_config (NM_VPN_CONNECTION (active)) + && !nm_active_connection_get_device (active)) + nm_active_connection_set_device (active, best); } + } + if (vpn) + default_device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); + else default_device = best; - } update_default_ac (policy, best_ac, nm_active_connection_set_default); @@ -710,90 +475,19 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) } static NMIP6Config * -get_best_ip6_config (NMPolicy *policy, +get_best_ip6_config (NMPolicy *self, gboolean ignore_never_default, const char **out_ip_iface, - int *out_ip_ifindex, NMActiveConnection **out_ac, NMDevice **out_device, - NMVPNConnection **out_vpn) + NMVpnConnection **out_vpn) { - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - const GSList *connections, *iter; - NMDevice *device; - NMActRequest *req = NULL; - NMIP6Config *ip6_config = NULL; - - /* If a VPN connection is active, it is preferred */ - connections = nm_manager_get_active_connections (priv->manager); - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMActiveConnection *active = NM_ACTIVE_CONNECTION (iter->data); - NMVPNConnection *candidate; - NMIP6Config *vpn_ip6; - NMConnection *tmp; - NMSettingIP6Config *s_ip6; - NMVPNConnectionState vpn_state; - - if (!NM_IS_VPN_CONNECTION (active)) - continue; - - candidate = NM_VPN_CONNECTION (active); - - tmp = nm_active_connection_get_connection (active); - g_assert (tmp); - - vpn_state = nm_vpn_connection_get_vpn_state (candidate); - if (vpn_state != NM_VPN_CONNECTION_STATE_ACTIVATED) - continue; - - vpn_ip6 = nm_vpn_connection_get_ip6_config (candidate); - if (!vpn_ip6) - continue; - - if (ignore_never_default == FALSE) { - /* Check for a VPN-provided config never-default */ - if (nm_ip6_config_get_never_default (vpn_ip6)) - continue; - - /* Check the user's preference from the NMConnection */ - s_ip6 = nm_connection_get_setting_ip6_config (tmp); - if (nm_setting_ip6_config_get_never_default (s_ip6)) - continue; - } - - ip6_config = vpn_ip6; - if (out_vpn) - *out_vpn = candidate; - if (out_ac) - *out_ac = NM_ACTIVE_CONNECTION (candidate); - if (out_ip_iface) - *out_ip_iface = nm_vpn_connection_get_ip_iface (candidate); - if (out_ip_ifindex) - *out_ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate); - break; - } - - /* If no VPN connections, we use the best device instead */ - if (!ip6_config) { - device = get_best_ip6_device (policy, TRUE); - if (device) { - req = nm_device_get_act_request (device); - g_assert (req); - ip6_config = nm_device_get_ip6_config (device); - g_assert (ip6_config); - - if (out_device) - *out_device = device; - if (out_ac) - *out_ac = NM_ACTIVE_CONNECTION (req); - if (out_ip_iface) - *out_ip_iface = nm_device_get_ip_iface (device); - if (out_ip_ifindex) - *out_ip_ifindex = nm_device_get_ip_ifindex (device); - } - } - - return ip6_config; + return nm_default_route_manager_ip6_get_best_config (nm_default_route_manager_get (), + ignore_never_default, + out_ip_iface, + out_ac, + out_device, + out_vpn); } static void @@ -801,10 +495,10 @@ update_ip6_dns (NMPolicy *policy, NMDnsManager *dns_mgr) { NMIP6Config *ip6_config; const char *ip_iface = NULL; - NMVPNConnection *vpn = NULL; + NMVpnConnection *vpn = NULL; NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; - ip6_config = get_best_ip6_config (policy, TRUE, &ip_iface, NULL, NULL, NULL, &vpn); + ip6_config = get_best_ip6_config (policy, TRUE, &ip_iface, NULL, NULL, &vpn); if (ip6_config) { if (vpn) dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; @@ -822,18 +516,14 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMDevice *best = NULL, *default_device6; NMConnection *connection = NULL; - NMVPNConnection *vpn = NULL; + NMVpnConnection *vpn = NULL; NMActiveConnection *best_ac = NULL; - NMIP6Config *ip6_config = NULL; const char *ip_iface = NULL; - int ip_ifindex = -1; - const struct in6_addr *gw_addr; /* Note that we might have an IPv6 VPN tunneled over an IPv4-only device, * so we can get (vpn != NULL && best == NULL). */ - ip6_config = get_best_ip6_config (policy, FALSE, &ip_iface, &ip_ifindex, &best_ac, &best, &vpn); - if (!ip6_config) { + if (!get_best_ip6_config (policy, FALSE, &ip_iface, &best_ac, &best, &vpn)) { gboolean changed; changed = (priv->default_device6 != NULL); @@ -848,59 +538,24 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) if (!force_update && best && (best == priv->default_device6)) return; - /* If no better gateway is found, use ::; not all configurations will - * have a gateway, especially WWAN/Point-to-Point connections. - */ - gw_addr = nm_ip6_config_get_gateway (ip6_config); - if (!gw_addr) - gw_addr = &in6addr_any; - - if (vpn) { - NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - int parent_ifindex = nm_device_get_ip_ifindex (parent); - NMIP6Config *parent_ip6 = nm_device_get_ip6_config (parent); - guint32 parent_mss = parent_ip6 ? nm_ip6_config_get_mss (parent_ip6) : 0; - const struct in6_addr *int_gw = nm_vpn_connection_get_ip6_internal_gateway (vpn); - int mss = nm_ip6_config_get_mss (ip6_config); - - if (!int_gw) - int_gw = &in6addr_any; - - /* If no VPN interface, use the parent interface */ - if (ip_ifindex <= 0) - ip_ifindex = parent_ifindex; - - if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, - in6addr_any, 0, *int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip6_route_add (parent_ifindex, NM_PLATFORM_SOURCE_VPN, - *gw_addr, 128, in6addr_any, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, parent_mss); - if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_VPN, - in6addr_any, 0, *int_gw, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set default route."); - } - } + if (best) { + const GSList *connections, *iter; - default_device6 = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - } else { - int mss = nm_ip6_config_get_mss (ip6_config); - - if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - in6addr_any, 0, *gw_addr, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) { - (void) nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - *gw_addr, 128, in6addr_any, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss); - if (!nm_platform_ip6_route_add (ip_ifindex, NM_PLATFORM_SOURCE_USER, - in6addr_any, 0, *gw_addr, - NM_PLATFORM_ROUTE_METRIC_DEFAULT, mss)) - nm_log_err (LOGD_IP6, "Failed to set default route."); + connections = nm_manager_get_active_connections (priv->manager); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMActiveConnection *active = iter->data; + + if ( NM_IS_VPN_CONNECTION (active) + && nm_vpn_connection_get_ip6_config (NM_VPN_CONNECTION (active)) + && !nm_active_connection_get_device (active)) + nm_active_connection_set_device (active, best); } + } + if (vpn) + default_device6 = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); + else default_device6 = best; - } update_default_ac (policy, best_ac, nm_active_connection_set_default6); @@ -985,7 +640,9 @@ auto_activate_device (gpointer user_data) NMPolicyPrivate *priv; NMConnection *best_connection; char *specific_object = NULL; - GSList *connections, *iter; + GPtrArray *connections; + GSList *connection_list; + guint i; g_assert (data); policy = data->policy; @@ -1000,20 +657,31 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - iter = connections = nm_manager_get_activatable_connections (priv->manager); + connection_list = nm_manager_get_activatable_connections (priv->manager); + if (!connection_list) + goto out; + + connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL); + g_slist_free (connection_list); - /* Remove connections that shouldn't be auto-activated */ - while (iter) { - NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data); + /* sort is stable (which is important at this point) so that connections + * with same priority are still sorted by last-connected-timestamp. */ + g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority); - /* Grab next item before we possibly delete the current item */ - iter = g_slist_next (iter); + /* Find the first connection that should be auto-activated */ + best_connection = NULL; + for (i = 0; i < connections->len; i++) { + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections->pdata[i]); if (!nm_settings_connection_can_autoconnect (candidate)) - connections = g_slist_remove (connections, candidate); + continue; + if (nm_device_can_auto_connect (data->device, (NMConnection *) candidate, &specific_object)) { + best_connection = (NMConnection *) candidate; + break; + } } + g_ptr_array_free (connections, TRUE); - best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); if (best_connection) { GError *error = NULL; NMAuthSubject *subject; @@ -1036,8 +704,6 @@ auto_activate_device (gpointer user_data) g_object_unref (subject); } - g_slist_free (connections); - out: activate_data_free (data); return G_SOURCE_REMOVE; @@ -1641,7 +1307,7 @@ device_autoconnect_changed (NMDevice *device, GParamSpec *pspec, gpointer user_data) { - if (nm_device_get_autoconnect (device)) + if (nm_device_autoconnect_allowed (device)) schedule_activate_check ((NMPolicy *) user_data, device); } @@ -1721,7 +1387,7 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data) /**************************************************************************/ static void -vpn_connection_activated (NMPolicy *policy, NMVPNConnection *vpn) +vpn_connection_activated (NMPolicy *policy, NMVpnConnection *vpn) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMIP4Config *ip4_config; @@ -1748,7 +1414,7 @@ vpn_connection_activated (NMPolicy *policy, NMVPNConnection *vpn) } static void -vpn_connection_deactivated (NMPolicy *policy, NMVPNConnection *vpn) +vpn_connection_deactivated (NMPolicy *policy, NMVpnConnection *vpn) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMIP4Config *ip4_config; @@ -1774,10 +1440,10 @@ vpn_connection_deactivated (NMPolicy *policy, NMVPNConnection *vpn) } static void -vpn_connection_state_changed (NMVPNConnection *vpn, - NMVPNConnectionState new_state, - NMVPNConnectionState old_state, - NMVPNConnectionStateReason reason, +vpn_connection_state_changed (NMVpnConnection *vpn, + NMVpnConnectionState new_state, + NMVpnConnectionState old_state, + NMVpnConnectionStateReason reason, NMPolicy *policy) { if (new_state == NM_VPN_CONNECTION_STATE_ACTIVATED) @@ -1790,6 +1456,28 @@ vpn_connection_state_changed (NMVPNConnection *vpn, } } +static void +vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *policy) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); + NMActiveConnection *ac = NM_ACTIVE_CONNECTION (vpn); + NMConnection *connection = nm_active_connection_get_connection (ac); + GError *error = NULL; + + /* Attempt to reconnect VPN connections that failed after being connected */ + if (!nm_manager_activate_connection (priv->manager, + connection, + NULL, + NULL, + nm_active_connection_get_subject (ac), + &error)) { + nm_log_warn (LOGD_DEVICE, "VPN '%s' reconnect failed: %s", + nm_connection_get_id (connection), + error->message ? error->message : "unknown"); + g_clear_error (&error); + } +} + static void active_connection_state_changed (NMActiveConnection *active, GParamSpec *pspec, @@ -1814,6 +1502,9 @@ active_connection_added (NMManager *manager, g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, G_CALLBACK (vpn_connection_state_changed), policy); + g_signal_connect (active, NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, + G_CALLBACK (vpn_connection_retry_after_failure), + policy); } g_signal_connect (active, "notify::" NM_ACTIVE_CONNECTION_STATE, @@ -1831,6 +1522,9 @@ active_connection_removed (NMManager *manager, g_signal_handlers_disconnect_by_func (active, vpn_connection_state_changed, policy); + g_signal_handlers_disconnect_by_func (active, + vpn_connection_retry_after_failure, + policy); g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, policy); @@ -1882,8 +1576,9 @@ firewall_update_zone (NMPolicy *policy, NMConnection *connection) NMDevice *dev = NM_DEVICE (iter->data); if ( (nm_device_get_connection (dev) == connection) - && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)) { - nm_firewall_manager_add_or_change_zone (priv->fw_manager, + && (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) + && !nm_device_uses_assumed_connection (dev)) { + nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (dev), nm_setting_connection_get_zone (s_con), FALSE, /* change zone */ @@ -1912,8 +1607,9 @@ firewall_started (NMFirewallManager *manager, continue; s_con = nm_connection_get_setting_connection (connection); - if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { - nm_firewall_manager_add_or_change_zone (priv->fw_manager, + if ( nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED + && !nm_device_uses_assumed_connection (dev)) { + nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), nm_device_get_ip_iface (dev), nm_setting_connection_get_zone (s_con), FALSE, /* still change zone */ @@ -1942,9 +1638,10 @@ dns_config_changed (NMDnsManager *dns_manager, gpointer user_data) /* Re-start the hostname lookup thread if we don't have hostname yet. */ if (priv->lookup_addr) { - char *str = g_inet_address_to_string (priv->lookup_addr); + char *str = NULL; - nm_log_dbg (LOGD_DNS, "restarting reverse-lookup thread for address %s", str); + nm_log_dbg (LOGD_DNS, "restarting reverse-lookup thread for address %s", + (str = g_inet_address_to_string (priv->lookup_addr))); g_free (str); priv->lookup_cancellable = g_cancellable_new (); @@ -2069,7 +1766,6 @@ nm_policy_new (NMManager *manager, NMSettings *settings) NMPolicy *policy; NMPolicyPrivate *priv; static gboolean initialized = FALSE; - gulong id; char hostname[HOST_NAME_MAX + 2]; g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); @@ -2085,17 +1781,12 @@ nm_policy_new (NMManager *manager, NMSettings *settings) memset (hostname, 0, sizeof (hostname)); if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) { /* only cache it if it's a valid hostname */ - if ( strlen (hostname) - && strcmp (hostname, "localhost") - && strcmp (hostname, "localhost.localdomain") - && strcmp (hostname, "(none)")) + if (*hostname && nm_utils_is_specific_hostname (hostname)) priv->orig_hostname = g_strdup (hostname); } - priv->fw_manager = nm_firewall_manager_get(); - id = g_signal_connect (priv->fw_manager, "started", - G_CALLBACK (firewall_started), policy); - priv->fw_started_id = id; + priv->fw_started_id = g_signal_connect (nm_firewall_manager_get (), "started", + G_CALLBACK (firewall_started), policy); priv->dns_manager = nm_dns_manager_get (); nm_dns_manager_set_initial_hostname (priv->dns_manager, priv->orig_hostname); @@ -2201,10 +1892,9 @@ dispose (GObject *object) g_slist_free_full (priv->pending_secondaries, (GDestroyNotify) pending_secondary_data_free); priv->pending_secondaries = NULL; - if (priv->fw_manager) { - g_signal_handler_disconnect (priv->fw_manager, priv->fw_started_id); - g_object_unref (priv->fw_manager); - priv->fw_manager = NULL; + if (priv->fw_started_id) { + g_signal_handler_disconnect (nm_firewall_manager_get (), priv->fw_started_id); + priv->fw_started_id = 0; } if (priv->dns_manager) { @@ -2260,30 +1950,26 @@ nm_policy_class_init (NMPolicyClass *policy_class) g_object_class_install_property (object_class, PROP_DEFAULT_IP4_DEVICE, - g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE, - "Default IP4 device", - "Default IP4 device", + g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_DEFAULT_IP6_DEVICE, - g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE, - "Default IP6 device", - "Default IP6 device", + g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVATING_IP4_DEVICE, - g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE, - "Activating default IP4 device", - "Activating default IP4 device", + g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_ACTIVATING_IP6_DEVICE, - g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE, - "Activating default IP6 device", - "Activating default IP6 device", + g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE, "", "", NM_TYPE_DEVICE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/nm-policy.h b/src/nm-policy.h index 6e83182a..76653529 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -19,11 +19,10 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifndef NM_POLICY_H -#define NM_POLICY_H +#ifndef __NETWORKMANAGER_POLICY_H__ +#define __NETWORKMANAGER_POLICY_H__ -#include "nm-manager.h" -#include "nm-settings.h" +#include "nm-types.h" #define NM_TYPE_POLICY (nm_policy_get_type ()) #define NM_POLICY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_POLICY, NMPolicy)) @@ -37,9 +36,9 @@ #define NM_POLICY_ACTIVATING_IP4_DEVICE "activating-ip4-device" #define NM_POLICY_ACTIVATING_IP6_DEVICE "activating-ip6-device" -typedef struct { +struct _NMPolicy { GObject parent; -} NMPolicy; +}; typedef struct { GObjectClass parent; @@ -55,4 +54,4 @@ NMDevice *nm_policy_get_default_ip6_device (NMPolicy *policy); NMDevice *nm_policy_get_activating_ip4_device (NMPolicy *policy); NMDevice *nm_policy_get_activating_ip6_device (NMPolicy *policy); -#endif /* NM_POLICY_H */ +#endif /* __NETWORKMANAGER_POLICY_H__ */ diff --git a/src/nm-posix-signals.c b/src/nm-posix-signals.c new file mode 100644 index 00000000..22fed831 --- /dev/null +++ b/src/nm-posix-signals.c @@ -0,0 +1,62 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-posix-signals.h" + + +/* Stores the original signal mask of NetworkManager process */ +static sigset_t nm_original_signal_mask; + +void +nm_save_original_signal_mask (sigset_t sig_mask) +{ + nm_original_signal_mask = sig_mask; +} + +const sigset_t * +nm_get_original_signal_mask (void) +{ + return &nm_original_signal_mask; +} + +/* + * Unblock signals. + * If a signal set is passed, those signals are unblocked. If user_data is NULL + * the process' signal mask is set to the saved original mask. + * Note: This function can be used in g_spawn_* as GSpawnChildSetupFunc() + * callback. + */ +void +nm_unblock_posix_signals (gpointer user_data) +{ + sigset_t *user_sigset = (sigset_t *) user_data; + + if (user_sigset != NULL) { + pthread_sigmask (SIG_UNBLOCK, user_sigset, NULL); + } else { + const sigset_t *orig_sig_mask = nm_get_original_signal_mask (); + pthread_sigmask (SIG_SETMASK, orig_sig_mask, NULL); + } +} + diff --git a/src/nm-posix-signals.h b/src/nm-posix-signals.h new file mode 100644 index 00000000..e2af559b --- /dev/null +++ b/src/nm-posix-signals.h @@ -0,0 +1,36 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2012 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_POSIX_SIGNALS_H__ +#define __NETWORKMANAGER_POSIX_SIGNALS_H__ + +#include +#include + +/* + * This function can be used in g_spawn_* as GSpawnChildSetupFunc() + * callback. + */ +void nm_unblock_posix_signals (gpointer user_data); + +void nm_save_original_signal_mask (sigset_t sig_mask); +const sigset_t *nm_get_original_signal_mask (void); + +#endif /* __NETWORKMANAGER_POSIX_SIGNALS_H__ */ diff --git a/src/nm-ppp-manager-glue.h b/src/nm-ppp-manager-glue.h index 4b215165..c3ba2ee4 100644 --- a/src/nm-ppp-manager-glue.h +++ b/src/nm-ppp-manager-glue.h @@ -161,13 +161,14 @@ G_END_DECLS static const DBusGMethodInfo dbus_glib_nm_ppp_manager_methods[] = { { (GCallback) impl_ppp_manager_need_secrets, dbus_glib_marshal_nm_ppp_manager_NONE__POINTER, 0 }, { (GCallback) impl_ppp_manager_set_ip4_config, dbus_glib_marshal_nm_ppp_manager_BOOLEAN__BOXED_POINTER, 84 }, - { (GCallback) impl_ppp_manager_set_state, dbus_glib_marshal_nm_ppp_manager_BOOLEAN__UINT_POINTER, 150 }, + { (GCallback) impl_ppp_manager_set_ip6_config, dbus_glib_marshal_nm_ppp_manager_BOOLEAN__BOXED_POINTER, 150 }, + { (GCallback) impl_ppp_manager_set_state, dbus_glib_marshal_nm_ppp_manager_BOOLEAN__UINT_POINTER, 216 }, }; const DBusGObjectInfo dbus_glib_nm_ppp_manager_object_info = { 1, dbus_glib_nm_ppp_manager_methods, - 3, -"org.freedesktop.NetworkManager.PPP\0NeedSecrets\0A\0username\0O\0F\0N\0s\0password\0O\0F\0N\0s\0\0org.freedesktop.NetworkManager.PPP\0SetIp4Config\0S\0config\0I\0a{sv}\0\0org.freedesktop.NetworkManager.PPP\0SetState\0S\0state\0I\0u\0\0\0", + 4, +"org.freedesktop.NetworkManager.PPP\0NeedSecrets\0A\0username\0O\0F\0N\0s\0password\0O\0F\0N\0s\0\0org.freedesktop.NetworkManager.PPP\0SetIp4Config\0S\0config\0I\0a{sv}\0\0org.freedesktop.NetworkManager.PPP\0SetIp6Config\0S\0config\0I\0a{sv}\0\0org.freedesktop.NetworkManager.PPP\0SetState\0S\0state\0I\0u\0\0\0", "\0", "\0" }; diff --git a/src/nm-properties-changed-signal.c b/src/nm-properties-changed-signal.c index 6e07c257..7ba62aa2 100644 --- a/src/nm-properties-changed-signal.c +++ b/src/nm-properties-changed-signal.c @@ -19,6 +19,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c index b02f85f5..27f3ca01 100644 --- a/src/nm-rfkill-manager.c +++ b/src/nm-rfkill-manager.c @@ -18,7 +18,7 @@ * Copyright (C) 2009 - 2013 Red Hat, Inc. */ -#include +#include "config.h" #include #include diff --git a/src/nm-rfkill-manager.h b/src/nm-rfkill-manager.h index b26261b8..220f3c2c 100644 --- a/src/nm-rfkill-manager.h +++ b/src/nm-rfkill-manager.h @@ -21,8 +21,10 @@ #include -#ifndef NM_RFKILL_MANAGER_H -#define NM_RFKILL_MANAGER_H +#include "nm-types.h" + +#ifndef __NETWORKMANAGER_RFKILL_MANAGER_H__ +#define __NETWORKMANAGER_RFKILL_MANAGER_H__ typedef enum { RFKILL_UNBLOCKED = 0, @@ -51,9 +53,9 @@ typedef enum { #define NM_IS_RFKILL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_RFKILL_MANAGER)) #define NM_RFKILL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RFKILL_MANAGER, NMRfkillManagerClass)) -typedef struct { +struct _NMRfkillManager { GObject parent; -} NMRfkillManager; +}; typedef struct { GObjectClass parent; diff --git a/src/nm-session-monitor-ck.c b/src/nm-session-monitor-ck.c index 75e1c927..964874bf 100644 --- a/src/nm-session-monitor-ck.c +++ b/src/nm-session-monitor-ck.c @@ -19,6 +19,7 @@ */ #include "config.h" + #include #include #include @@ -27,6 +28,7 @@ #include "nm-session-utils.h" #include "nm-session-monitor.h" +#include "nm-errors.h" /* * SECTION:nm-session-monitor @@ -86,8 +88,8 @@ check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error if (!error) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key", group, key); } @@ -175,8 +177,8 @@ reload_database (NMSessionMonitor *self, GError **error) errno = 0; if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Error statting file " CKDB_PATH ": %s", strerror (errno)); goto error; @@ -190,8 +192,8 @@ reload_database (NMSessionMonitor *self, GError **error) groups = g_key_file_get_groups (self->database, &len); if (!groups) { g_set_error_literal (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_IO_ERROR, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not load groups from " CKDB_PATH ""); goto error; } @@ -238,8 +240,8 @@ ensure_database (NMSessionMonitor *self, GError **error) errno = 0; if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - errno == ENOENT ? NM_SESSION_MONITOR_ERROR_NO_DATABASE : NM_SESSION_MONITOR_ERROR_IO_ERROR, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Error statting file " CKDB_PATH " to check timestamp: %s", strerror (errno)); goto out; @@ -284,18 +286,14 @@ nm_session_monitor_init (NMSessionMonitor *self) self->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal); - error = NULL; if (!ensure_database (self, &error)) { - /* Ignore the first error if the CK database isn't found yet */ - if (g_error_matches (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_NO_DATABASE) == FALSE) { - nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); - } + nm_log_dbg (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); + + /* Ignore the first error, the CK database might not exist yet */ g_error_free (error); + error = NULL; } - error = NULL; file = g_file_new_for_path (CKDB_PATH); self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); g_object_unref (file); @@ -386,8 +384,8 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); if (!s) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "No session found for user '%s'", username); return FALSE; @@ -423,8 +421,8 @@ nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); if (!s) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "No session found for uid %d", uid); return FALSE; @@ -459,8 +457,8 @@ nm_session_monitor_user_active (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); if (!s) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "No session found for user '%s'", username); return FALSE; @@ -493,8 +491,8 @@ nm_session_monitor_uid_active (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); if (!s) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "No session found for uid '%d'", uid); return FALSE; diff --git a/src/nm-session-monitor-null.c b/src/nm-session-monitor-null.c index 5d8ecaaf..bffb75d3 100644 --- a/src/nm-session-monitor-null.c +++ b/src/nm-session-monitor-null.c @@ -19,6 +19,7 @@ */ #include "config.h" + #include #include "nm-logging.h" diff --git a/src/nm-session-monitor-systemd.c b/src/nm-session-monitor-systemd.c index f195c1e7..dcb0004d 100644 --- a/src/nm-session-monitor-systemd.c +++ b/src/nm-session-monitor-systemd.c @@ -21,6 +21,7 @@ */ #include "config.h" + #include #include #include diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h index 77ea9a03..3efe6eca 100644 --- a/src/nm-session-monitor.h +++ b/src/nm-session-monitor.h @@ -18,11 +18,13 @@ * Author: Dan Williams */ -#ifndef NM_SESSION_MONITOR_H -#define NM_SESSION_MONITOR_H +#ifndef __NETWORKMANAGER_SESSION_MONITOR_H__ +#define __NETWORKMANAGER_SESSION_MONITOR_H__ #include +#include "nm-types.h" + G_BEGIN_DECLS #define NM_TYPE_SESSION_MONITOR (nm_session_monitor_get_type ()) @@ -34,7 +36,6 @@ G_BEGIN_DECLS #define NM_SESSION_MONITOR_CHANGED "changed" -typedef struct _NMSessionMonitor NMSessionMonitor; typedef struct _NMSessionMonitorClass NMSessionMonitorClass; GType nm_session_monitor_get_type (void) G_GNUC_CONST; @@ -60,5 +61,5 @@ gboolean nm_session_monitor_uid_active (NMSessionMonitor *monitor G_END_DECLS -#endif /* NM_SESSION_MONITOR_H */ +#endif /* __NETWORKMANAGER_SESSION_MONITOR_H__ */ diff --git a/src/nm-session-utils.c b/src/nm-session-utils.c index 269e2f81..eb156fad 100644 --- a/src/nm-session-utils.c +++ b/src/nm-session-utils.c @@ -17,22 +17,13 @@ * Author: Dan Williams */ +#include "config.h" + #include #include #include "nm-session-utils.h" - -/********************************************************************/ - -GQuark -nm_session_monitor_error_quark (void) -{ - static GQuark ret = 0; - - if (G_UNLIKELY (ret == 0)) - ret = g_quark_from_static_string ("nm-session-monitor-error"); - return ret; -} +#include "nm-errors.h" /********************************************************************/ @@ -44,8 +35,8 @@ nm_session_uid_to_user (uid_t uid, const char **out_user, GError **error) pw = getpwuid (uid); if (!pw) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not get username for UID %d", uid); return FALSE; @@ -64,8 +55,8 @@ nm_session_user_to_uid (const char *user, uid_t *out_uid, GError **error) pw = getpwnam (user); if (!pw) { g_set_error (error, - NM_SESSION_MONITOR_ERROR, - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "Could not get UID for username '%s'", user); return FALSE; diff --git a/src/nm-session-utils.h b/src/nm-session-utils.h index 54b6d4c4..e626f52a 100644 --- a/src/nm-session-utils.h +++ b/src/nm-session-utils.h @@ -17,23 +17,12 @@ * Author: Dan Williams */ -#ifndef NM_SESSION_UTILS_H -#define NM_SESSION_UTILS_H +#ifndef __NETWORKMANAGER_SESSION_UTILS_H__ +#define __NETWORKMANAGER_SESSION_UTILS_H__ #include #include -#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ()) -GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST; -GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; - -typedef enum { - NM_SESSION_MONITOR_ERROR_IO_ERROR = 0, /*< nick=IOError >*/ - NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, /*< nick=MalformedDatabase >*/ - NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, /*< nick=UnknownUser >*/ - NM_SESSION_MONITOR_ERROR_NO_DATABASE, /*< nick=NoDatabase >*/ -} NMSessionMonitorError; - gboolean nm_session_uid_to_user (uid_t uid, const char **out_user, GError **error); gboolean nm_session_user_to_uid (const char *user, uid_t *out_uid, GError **error); diff --git a/src/nm-settings-connection-glue.h b/src/nm-settings-connection-glue.h index 8cace513..23797562 100644 --- a/src/nm-settings-connection-glue.h +++ b/src/nm-settings-connection-glue.h @@ -158,13 +158,14 @@ static const DBusGMethodInfo dbus_glib_nm_settings_connection_methods[] = { { (GCallback) impl_settings_connection_delete, dbus_glib_marshal_nm_settings_connection_NONE__POINTER, 175 }, { (GCallback) impl_settings_connection_get_settings, dbus_glib_marshal_nm_settings_connection_NONE__POINTER, 236 }, { (GCallback) impl_settings_connection_get_secrets, dbus_glib_marshal_nm_settings_connection_NONE__STRING_POINTER, 327 }, - { (GCallback) impl_settings_connection_save, dbus_glib_marshal_nm_settings_connection_NONE__POINTER, 433 }, + { (GCallback) impl_settings_connection_clear_secrets, dbus_glib_marshal_nm_settings_connection_NONE__POINTER, 433 }, + { (GCallback) impl_settings_connection_save, dbus_glib_marshal_nm_settings_connection_NONE__POINTER, 500 }, }; const DBusGObjectInfo dbus_glib_nm_settings_connection_object_info = { 1, dbus_glib_nm_settings_connection_methods, - 6, -"org.freedesktop.NetworkManager.Settings.Connection\0Update\0A\0properties\0I\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0UpdateUnsaved\0A\0properties\0I\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0Delete\0A\0\0org.freedesktop.NetworkManager.Settings.Connection\0GetSettings\0A\0settings\0O\0F\0N\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0GetSecrets\0A\0setting_name\0I\0s\0secrets\0O\0F\0N\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0Save\0A\0\0\0", + 7, +"org.freedesktop.NetworkManager.Settings.Connection\0Update\0A\0properties\0I\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0UpdateUnsaved\0A\0properties\0I\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0Delete\0A\0\0org.freedesktop.NetworkManager.Settings.Connection\0GetSettings\0A\0settings\0O\0F\0N\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0GetSecrets\0A\0setting_name\0I\0s\0secrets\0O\0F\0N\0a{sa{sv}}\0\0org.freedesktop.NetworkManager.Settings.Connection\0ClearSecrets\0A\0\0org.freedesktop.NetworkManager.Settings.Connection\0Save\0A\0\0\0", "org.freedesktop.NetworkManager.Settings.Connection\0Updated\0org.freedesktop.NetworkManager.Settings.Connection\0Removed\0org.freedesktop.NetworkManager.Settings.Connection\0PropertiesChanged\0\0", "org.freedesktop.NetworkManager.Settings.Connection\0Unsaved\0unsaved\0read\0\0" }; diff --git a/src/nm-sleep-monitor-systemd.c b/src/nm-sleep-monitor-systemd.c index 55134c48..c0bc65e4 100644 --- a/src/nm-sleep-monitor-systemd.c +++ b/src/nm-sleep-monitor-systemd.c @@ -18,11 +18,10 @@ */ #include "config.h" + #include #include #include -#include -#include #include #include #include @@ -149,24 +148,59 @@ signal_cb (GDBusProxy *proxy, } static void -sleep_setup (NMSleepMonitor *self) +name_owner_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - GDBusConnection *bus; + GDBusProxy *proxy = G_DBUS_PROXY (object); + NMSleepMonitor *self = NM_SLEEP_MONITOR (user_data); + char *owner; + + g_assert (proxy == self->sd_proxy); + + owner = g_dbus_proxy_get_name_owner (proxy); + if (owner) + take_inhibitor (self); + else + drop_inhibitor (self); + g_free (owner); +} - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); - self->sd_proxy = g_dbus_proxy_new_sync (bus, 0, NULL, - SD_NAME, SD_PATH, SD_INTERFACE, - NULL, NULL); - g_object_unref (bus); +static void +on_proxy_acquired (GObject *object, + GAsyncResult *res, + NMSleepMonitor *self) +{ + GError *error = NULL; + char *owner; + + self->sd_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + if (!self->sd_proxy) { + nm_log_warn (LOGD_SUSPEND, "Failed to acquire logind proxy: %s", error->message); + g_clear_error (&error); + return; + } + + g_signal_connect (self->sd_proxy, "notify::g-name-owner", G_CALLBACK (name_owner_cb), self); g_signal_connect (self->sd_proxy, "g-signal", G_CALLBACK (signal_cb), self); + + owner = g_dbus_proxy_get_name_owner (self->sd_proxy); + if (owner) + take_inhibitor (self); + g_free (owner); } static void nm_sleep_monitor_init (NMSleepMonitor *self) { self->inhibit_fd = -1; - sleep_setup (self); - take_inhibitor (self); + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + SD_NAME, SD_PATH, SD_INTERFACE, + NULL, + (GAsyncReadyCallback) on_proxy_acquired, self); } static void diff --git a/src/nm-sleep-monitor-upower.c b/src/nm-sleep-monitor-upower.c index 58402abd..39cce595 100644 --- a/src/nm-sleep-monitor-upower.c +++ b/src/nm-sleep-monitor-upower.c @@ -18,6 +18,7 @@ */ #include "config.h" + #include #include #include diff --git a/src/nm-sleep-monitor.h b/src/nm-sleep-monitor.h index 173e6a13..84623771 100644 --- a/src/nm-sleep-monitor.h +++ b/src/nm-sleep-monitor.h @@ -17,11 +17,13 @@ * Author: Matthias Clasen */ -#ifndef NM_SLEEP_MONITOR_H -#define NM_SLEEP_MONITOR_H +#ifndef __NETWORKMANAGER_SLEEP_MONITOR_H__ +#define __NETWORKMANAGER_SLEEP_MONITOR_H__ #include +#include "nm-types.h" + G_BEGIN_DECLS #define NM_TYPE_SLEEP_MONITOR (nm_sleep_monitor_get_type ()) @@ -34,7 +36,6 @@ G_BEGIN_DECLS #define NM_SLEEP_MONITOR_SLEEPING "sleeping" #define NM_SLEEP_MONITOR_RESUMING "resuming" -typedef struct _NMSleepMonitor NMSleepMonitor; typedef struct _NMSleepMonitorClass NMSleepMonitorClass; GType nm_sleep_monitor_get_type (void) G_GNUC_CONST; @@ -42,5 +43,5 @@ NMSleepMonitor *nm_sleep_monitor_get (void); G_END_DECLS -#endif /* NM_SLEEP_MONITOR_H */ +#endif /* __NETWORKMANAGER_SLEEP_MONITOR_H__ */ diff --git a/src/nm-types.h b/src/nm-types.h index c558d7ba..4a93567e 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -18,9 +18,97 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#ifndef NM_TYPES_H -#define NM_TYPES_H +#ifndef __NETWORKMANAGER_TYPES_H__ +#define __NETWORKMANAGER_TYPES_H__ -typedef struct _NMDevice NMDevice; +/* core */ +typedef struct _NMActiveConnection NMActiveConnection; +typedef struct _NMVpnConnection NMVpnConnection; +typedef struct _NMActRequest NMActRequest; +typedef struct _NMAuthSubject NMAuthSubject; +typedef struct _NMConnectionProvider NMConnectionProvider; +typedef struct _NMConnectivity NMConnectivity; +typedef struct _NMDBusManager NMDBusManager; +typedef struct _NMDefaultRouteManager NMDefaultRouteManager; +typedef struct _NMDevice NMDevice; +typedef struct _NMDhcp4Config NMDhcp4Config; +typedef struct _NMDhcp6Config NMDhcp6Config; +typedef struct _NMIP4Config NMIP4Config; +typedef struct _NMIP6Config NMIP6Config; +typedef struct _NMManager NMManager; +typedef struct _NMPolicy NMPolicy; +typedef struct _NMRfkillManager NMRfkillManager; +typedef struct _NMSessionMonitor NMSessionMonitor; +typedef struct _NMSleepMonitor NMSleepMonitor; + +typedef enum { + /* In priority order; higher number == higher priority */ + NM_IP_CONFIG_SOURCE_UNKNOWN, + NM_IP_CONFIG_SOURCE_KERNEL, + NM_IP_CONFIG_SOURCE_SHARED, + NM_IP_CONFIG_SOURCE_IP4LL, + NM_IP_CONFIG_SOURCE_PPP, + NM_IP_CONFIG_SOURCE_WWAN, + NM_IP_CONFIG_SOURCE_VPN, + NM_IP_CONFIG_SOURCE_DHCP, + NM_IP_CONFIG_SOURCE_RDISC, + NM_IP_CONFIG_SOURCE_USER, +} NMIPConfigSource; + +/* platform */ +typedef struct _NMPlatformIP4Address NMPlatformIP4Address; +typedef struct _NMPlatformIP4Route NMPlatformIP4Route; +typedef struct _NMPlatformIP6Address NMPlatformIP6Address; +typedef struct _NMPlatformIP6Route NMPlatformIP6Route; +typedef struct _NMPlatformLink NMPlatformLink; + +typedef enum { + /* Please don't interpret type numbers outside nm-platform and use functions + * like nm_platform_link_is_software() and nm_platform_supports_slaves(). + * + * type & 0x10000 -> Software device type + * type & 0x20000 -> Type supports slaves + */ + + /* No type, used as error value */ + NM_LINK_TYPE_NONE, + + /* Unknown type */ + NM_LINK_TYPE_UNKNOWN, + + /* Hardware types */ + NM_LINK_TYPE_ETHERNET, + NM_LINK_TYPE_INFINIBAND, + NM_LINK_TYPE_OLPC_MESH, + NM_LINK_TYPE_WIFI, + NM_LINK_TYPE_WWAN_ETHERNET, /* WWAN pseudo-ethernet */ + NM_LINK_TYPE_WIMAX, + + /* Software types */ + NM_LINK_TYPE_DUMMY = 0x10000, + NM_LINK_TYPE_GRE, + NM_LINK_TYPE_GRETAP, + NM_LINK_TYPE_IFB, + NM_LINK_TYPE_LOOPBACK, + NM_LINK_TYPE_MACVLAN, + NM_LINK_TYPE_MACVTAP, + NM_LINK_TYPE_OPENVSWITCH, + NM_LINK_TYPE_TAP, + NM_LINK_TYPE_TUN, + NM_LINK_TYPE_VETH, + NM_LINK_TYPE_VLAN, + NM_LINK_TYPE_VXLAN, + + /* Software types with slaves */ + NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000, + NM_LINK_TYPE_BOND, + NM_LINK_TYPE_TEAM, +} NMLinkType; + +/* settings */ +typedef struct _NMAgentManager NMAgentManager; +typedef struct _NMSecretAgent NMSecretAgent; +typedef struct _NMSettings NMSettings; +typedef struct _NMSettingsConnection NMSettingsConnection; #endif /* NM_TYPES_H */ diff --git a/src/platform/Makefile.in b/src/platform/Makefile.in index 9358879f..d4c8ade7 100644 --- a/src/platform/Makefile.in +++ b/src/platform/Makefile.in @@ -189,6 +189,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -312,6 +314,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -331,6 +334,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -357,7 +361,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 46272217..a5eb7d4e 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -18,11 +18,14 @@ * Copyright (C) 2012–2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include +#include "gsystem-local-alloc.h" #include "NetworkManagerUtils.h" #include "nm-fake-platform.h" #include "nm-logging.h" @@ -162,12 +165,12 @@ link_get_all (NMPlatform *platform) } static gboolean -_nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *link) +_nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *l) { NMFakePlatformLink *device = link_get (platform, ifindex); if (device) - *link = device->link; + *l = device->link; return !!device; } @@ -543,7 +546,7 @@ link_get_master (NMPlatform *platform, int slave) static gboolean master_set_option (NMPlatform *platform, int master, const char *option, const char *value) { - auto_g_free char *path = g_strdup_printf ("master:%d:%s", master, option); + gs_free char *path = g_strdup_printf ("master:%d:%s", master, option); return sysctl_set (platform, path, value); } @@ -551,7 +554,7 @@ master_set_option (NMPlatform *platform, int master, const char *option, const c static char * master_get_option (NMPlatform *platform, int master, const char *option) { - auto_g_free char *path = g_strdup_printf ("master:%d:%s", master, option); + gs_free char *path = g_strdup_printf ("master:%d:%s", master, option); return sysctl_get (platform, path); } @@ -559,7 +562,7 @@ master_get_option (NMPlatform *platform, int master, const char *option) static gboolean slave_set_option (NMPlatform *platform, int slave, const char *option, const char *value) { - auto_g_free char *path = g_strdup_printf ("slave:%d:%s", slave, option); + gs_free char *path = g_strdup_printf ("slave:%d:%s", slave, option); return sysctl_set (platform, path, value); } @@ -567,7 +570,7 @@ slave_set_option (NMPlatform *platform, int slave, const char *option, const cha static char * slave_get_option (NMPlatform *platform, int slave, const char *option) { - auto_g_free char *path = g_strdup_printf ("slave:%d:%s", slave, option); + gs_free char *path = g_strdup_printf ("slave:%d:%s", slave, option); return sysctl_get (platform, path); } @@ -688,7 +691,7 @@ wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabiliti } static gboolean -wifi_get_bssid (NMPlatform *platform, int ifindex, struct ether_addr *bssid) +wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) { return FALSE; } @@ -754,7 +757,7 @@ mesh_set_channel (NMPlatform *platform, int ifindex, guint32 channel) } static gboolean -mesh_set_ssid (NMPlatform *platform, int ifindex, const GByteArray *ssid) +mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) { return FALSE; } @@ -827,7 +830,7 @@ ip4_address_add (NMPlatform *platform, int ifindex, int i; memset (&address, 0, sizeof (address)); - address.source = NM_PLATFORM_SOURCE_KERNEL; + address.source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = peer_addr; @@ -869,7 +872,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, int i; memset (&address, 0, sizeof (address)); - address.source = NM_PLATFORM_SOURCE_KERNEL; + address.source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = peer_addr; @@ -901,7 +904,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -909,7 +912,8 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) for (i = 0; i < priv->ip4_addresses->len; i++) { NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i); - if (address->ifindex == ifindex && address->plen == plen && address->address == addr) { + if (address->ifindex == ifindex && address->plen == plen && address->address == addr && + (!peer_address || address->peer_address == peer_address)) { NMPlatformIP4Address deleted_address; memcpy (&deleted_address, address, sizeof (deleted_address)); @@ -978,31 +982,37 @@ ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int return FALSE; } +static gboolean +ip4_check_reinstall_device_route (NMPlatform *platform, int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric) +{ + return FALSE; +} + /******************************************************************/ static GArray * -ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) +ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); GArray *routes; NMPlatformIP4Route *route; - int count = 0, i; + guint i; - /* Count routes */ - for (i = 0; i < priv->ip4_routes->len; i++) { - route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i); - if (route && route->ifindex == ifindex) - count++; - } + g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL); - routes = g_array_sized_new (TRUE, TRUE, sizeof (NMPlatformIP4Route), count); + routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP4Route)); /* Fill routes */ for (i = 0; i < priv->ip4_routes->len; i++) { route = &g_array_index (priv->ip4_routes, NMPlatformIP4Route, i); - if (route && route->ifindex == ifindex) { - if (route->plen != 0 || include_default) - g_array_append_val (routes, *route); + if (route && (!ifindex || route->ifindex == ifindex)) { + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { + if (mode != NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT) + g_array_append_val (routes, *route); + } else { + if (mode != NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT) + g_array_append_val (routes, *route); + } } } @@ -1010,28 +1020,28 @@ ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) } static GArray * -ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) +ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); GArray *routes; NMPlatformIP6Route *route; - int count = 0, i; + guint i; - /* Count routes */ - for (i = 0; i < priv->ip6_routes->len; i++) { - route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i); - if (route && route->ifindex == ifindex) - count++; - } + g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL); - routes = g_array_sized_new (TRUE, TRUE, sizeof (NMPlatformIP6Route), count); + routes = g_array_new (TRUE, TRUE, sizeof (NMPlatformIP6Route)); /* Fill routes */ for (i = 0; i < priv->ip6_routes->len; i++) { route = &g_array_index (priv->ip6_routes, NMPlatformIP6Route, i); - if (route && route->ifindex == ifindex) { - if (route->plen != 0 || include_default) - g_array_append_val (routes, *route); + if (route && (!ifindex || route->ifindex == ifindex)) { + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) { + if (mode != NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT) + g_array_append_val (routes, *route); + } else { + if (mode != NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT) + g_array_append_val (routes, *route); + } } } @@ -1039,16 +1049,16 @@ ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, +ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, in_addr_t network, int plen, in_addr_t gateway, - int metric, int mss) + guint32 pref_src, guint32 metric, guint32 mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP4Route route; guint i; memset (&route, 0, sizeof (route)); - route.source = NM_PLATFORM_SOURCE_KERNEL; + route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; route.source = source; route.network = network; @@ -1079,16 +1089,16 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, +ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, - int metric, int mss) + guint32 metric, guint32 mss) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Route route; guint i; memset (&route, 0, sizeof (route)); - route.source = NM_PLATFORM_SOURCE_KERNEL; + route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; route.source = source; route.network = network; @@ -1119,7 +1129,7 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, } static NMPlatformIP4Route * -ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, int metric) +ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1138,7 +1148,7 @@ ip4_route_get (NMPlatform *platform, int ifindex, in_addr_t network, int plen, i } static NMPlatformIP6Route * -ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, int metric) +ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -1157,7 +1167,7 @@ ip6_route_get (NMPlatform *platform, int ifindex, struct in6_addr network, int p } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, int metric) +ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) { NMPlatformIP4Route *route = ip4_route_get (platform, ifindex, network, plen, metric); NMPlatformIP4Route deleted_route; @@ -1172,7 +1182,7 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, int metric) +ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { NMPlatformIP6Route *route = ip6_route_get (platform, ifindex, network, plen, metric); NMPlatformIP6Route deleted_route; @@ -1187,13 +1197,13 @@ ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, in } static gboolean -ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, int metric) +ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) { return !!ip4_route_get (platform, ifindex, network, plen, metric); } static gboolean -ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, int metric) +ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { return !!ip6_route_get (platform, ifindex, network, plen, metric); } @@ -1341,6 +1351,8 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->ip4_address_exists = ip4_address_exists; platform_class->ip6_address_exists = ip6_address_exists; + platform_class->ip4_check_reinstall_device_route = ip4_check_reinstall_device_route; + platform_class->ip4_route_get_all = ip4_route_get_all; platform_class->ip6_route_get_all = ip6_route_get_all; platform_class->ip4_route_add = ip4_route_add; diff --git a/src/platform/nm-fake-platform.h b/src/platform/nm-fake-platform.h index c9fa42eb..53a2ff1a 100644 --- a/src/platform/nm-fake-platform.h +++ b/src/platform/nm-fake-platform.h @@ -18,8 +18,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#ifndef NM_FAKE_PLATFORM_H -#define NM_FAKE_PLATFORM_H +#ifndef __NETWORKMANAGER_FAKE_PLATFORM_H__ +#define __NETWORKMANAGER_FAKE_PLATFORM_H__ #include "nm-platform.h" @@ -46,4 +46,4 @@ GType nm_fake_platform_get_type (void); void nm_fake_platform_setup (void); -#endif /* NM_FAKE_PLATFORM_H */ +#endif /* __NETWORKMANAGER_FAKE_PLATFORM_H__ */ diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f73ff320..5d1522ce 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -17,7 +17,7 @@ * * Copyright (C) 2012-2013 Red Hat, Inc. */ -#include +#include "config.h" #include #include @@ -44,6 +44,17 @@ #include #include +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE +#include +#if HAVE_KERNEL_INET6_ADDR_GEN_MODE +#include +#else +#define IN6_ADDR_GEN_MODE_EUI64 0 +#define IN6_ADDR_GEN_MODE_NONE 1 +#endif +#endif + +#include "gsystem-local-alloc.h" #include "NetworkManagerUtils.h" #include "nm-linux-platform.h" #include "NetworkManagerUtils.h" @@ -83,6 +94,7 @@ typedef struct { GHashTable *wifi_data; int support_kernel_extended_ifa_flags; + int support_user_ipv6ll; } NMLinuxPlatformPrivate; #define NM_LINUX_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate)) @@ -90,6 +102,8 @@ typedef struct { G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) static const char *to_string_object (NMPlatform *platform, struct nl_object *obj); +static gboolean _address_match (struct rtnl_addr *addr, int family, int ifindex); +static gboolean _route_match (struct rtnl_route *rtnlroute, int family, int ifindex, gboolean include_proto_kernel); void nm_linux_platform_setup (void) @@ -106,7 +120,7 @@ _nl_f_nl_has_capability (int capability) } static struct libnl_vtable * -_nl_get_vtable () +_nl_get_vtable (void) { static struct libnl_vtable vtable; @@ -268,7 +282,7 @@ _nm_rtnl_addr_alloc (int ifindex) } static struct rtnl_route * -_nm_rtnl_route_alloc () +_nm_rtnl_route_alloc (void) { struct rtnl_route *rtnlroute = rtnl_route_alloc (); @@ -278,7 +292,7 @@ _nm_rtnl_route_alloc () } static struct rtnl_nexthop * -_nm_rtnl_route_nh_alloc () +_nm_rtnl_route_nh_alloc (void) { struct rtnl_nexthop *nexthop; @@ -596,8 +610,8 @@ ethtool_get (const char *name, gpointer edata) static int ethtool_get_stringset_index (const char *ifname, int stringset_id, const char *string) { - auto_g_free struct ethtool_sset_info *info = NULL; - auto_g_free struct ethtool_gstrings *strings = NULL; + gs_free struct ethtool_sset_info *info = NULL; + gs_free struct ethtool_gstrings *strings = NULL; guint32 len, i; info = g_malloc0 (sizeof (*info) + sizeof (guint32)); @@ -667,6 +681,23 @@ check_support_kernel_extended_ifa_flags (NMPlatform *platform) return priv->support_kernel_extended_ifa_flags > 0; } +static gboolean +check_support_user_ipv6ll (NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv; + + g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), FALSE); + + priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + + if (priv->support_user_ipv6ll == 0) { + nm_log_warn (LOGD_PLATFORM, "Unable to detect kernel support for IFLA_INET6_ADDR_GEN_MODE. Assume no kernel support."); + priv->support_user_ipv6ll = -1; + } + + return priv->support_user_ipv6ll > 0; +} + /* Object type specific utilities */ @@ -735,7 +766,7 @@ link_type_from_udev (NMPlatform *platform, int ifindex, const char *ifname, int prop = g_udev_device_get_property (udev_device, "DEVTYPE"); sysfs_path = g_udev_device_get_sysfs_path (udev_device); - if (g_strcmp0 (prop, "wlan") == 0 || wifi_utils_is_wifi (ifname, sysfs_path)) + if (wifi_utils_is_wifi (ifname, sysfs_path, prop)) return_type (NM_LINK_TYPE_WIFI, "wifi"); else if (g_strcmp0 (prop, "wwan") == 0) return_type (NM_LINK_TYPE_WWAN_ETHERNET, "wwan"); @@ -1176,7 +1207,7 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr) memset (address, 0, sizeof (*address)); - address->source = NM_PLATFORM_SOURCE_KERNEL; + address->source = NM_IP_CONFIG_SOURCE_KERNEL; address->ifindex = rtnl_addr_get_ifindex (rtnladdr); address->plen = rtnl_addr_get_prefixlen (rtnladdr); _init_ip_address_lifetime ((NMPlatformIPAddress *) address, rtnladdr); @@ -1208,7 +1239,7 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) memset (address, 0, sizeof (*address)); - address->source = NM_PLATFORM_SOURCE_KERNEL; + address->source = NM_IP_CONFIG_SOURCE_KERNEL; address->ifindex = rtnl_addr_get_ifindex (rtnladdr); address->plen = rtnl_addr_get_prefixlen (rtnladdr); _init_ip_address_lifetime ((NMPlatformIPAddress *) address, rtnladdr); @@ -1230,16 +1261,16 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) } static guint -source_to_rtprot (NMPlatformSource source) +source_to_rtprot (NMIPConfigSource source) { switch (source) { - case NM_PLATFORM_SOURCE_UNKNOWN: + case NM_IP_CONFIG_SOURCE_UNKNOWN: return RTPROT_UNSPEC; - case NM_PLATFORM_SOURCE_KERNEL: + case NM_IP_CONFIG_SOURCE_KERNEL: return RTPROT_KERNEL; - case NM_PLATFORM_SOURCE_DHCP: + case NM_IP_CONFIG_SOURCE_DHCP: return RTPROT_DHCP; - case NM_PLATFORM_SOURCE_RDISC: + case NM_IP_CONFIG_SOURCE_RDISC: return RTPROT_RA; default: @@ -1247,25 +1278,35 @@ source_to_rtprot (NMPlatformSource source) } } -static NMPlatformSource +static NMIPConfigSource rtprot_to_source (guint rtprot) { switch (rtprot) { case RTPROT_UNSPEC: - return NM_PLATFORM_SOURCE_UNKNOWN; + return NM_IP_CONFIG_SOURCE_UNKNOWN; case RTPROT_REDIRECT: case RTPROT_KERNEL: - return NM_PLATFORM_SOURCE_KERNEL; + return NM_IP_CONFIG_SOURCE_KERNEL; case RTPROT_RA: - return NM_PLATFORM_SOURCE_RDISC; + return NM_IP_CONFIG_SOURCE_RDISC; case RTPROT_DHCP: - return NM_PLATFORM_SOURCE_DHCP; + return NM_IP_CONFIG_SOURCE_DHCP; default: - return NM_PLATFORM_SOURCE_USER; + return NM_IP_CONFIG_SOURCE_USER; } } +static gboolean +_rtnl_route_is_default (const struct rtnl_route *rtnlroute) +{ + struct nl_addr *dst; + + return rtnlroute + && (dst = rtnl_route_get_dst ((struct rtnl_route *) rtnlroute)) + && nl_addr_get_prefixlen (dst) == 0; +} + static gboolean init_ip4_route (NMPlatformIP4Route *route, struct rtnl_route *rtnlroute) { @@ -1527,8 +1568,20 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor switch (object_type) { case OBJECT_TYPE_LINK: { - NMPlatformLink device; struct rtnl_link *rtnl_link = (struct rtnl_link *) object; + NMPlatformLink device; + +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + /* If we ever see a link with valid IPv6 link-local address + * generation modes, the kernel supports it. + */ + if (priv->support_user_ipv6ll == 0) { + uint8_t mode; + + if (rtnl_link_inet6_get_addr_gen_mode (rtnl_link, &mode) == 0) + priv->support_user_ipv6ll = 1; + } +#endif if (!init_link (platform, &device, rtnl_link)) return; @@ -1576,20 +1629,25 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP4Address address; - if (!init_ip4_address (&address, (struct rtnl_addr *) object)) - return; - /* Address deletion is sometimes accompanied by route deletion. We need to * check all routes belonging to the same interface. */ switch (change_type) { case NM_PLATFORM_SIGNAL_REMOVED: - check_cache_items (platform, priv->route_cache, address.ifindex); + check_cache_items (platform, + priv->route_cache, + rtnl_addr_get_ifindex ((struct rtnl_addr *) object)); break; default: break; } + if (!_address_match ((struct rtnl_addr *) object, AF_INET, 0)) { + nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP4 address %s", to_string_ip4_address ((struct rtnl_addr *) object)); + return; + } + if (!init_ip4_address (&address, (struct rtnl_addr *) object)) + return; g_signal_emit_by_name (platform, sig, address.ifindex, &address, change_type, reason); } return; @@ -1597,6 +1655,10 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP6Address address; + if (!_address_match ((struct rtnl_addr *) object, AF_INET6, 0)) { + nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP6 address %s", to_string_ip6_address ((struct rtnl_addr *) object)); + return; + } if (!init_ip6_address (&address, (struct rtnl_addr *) object)) return; g_signal_emit_by_name (platform, sig, address.ifindex, &address, change_type, reason); @@ -1606,6 +1668,10 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP4Route route; + if (!_route_match ((struct rtnl_route *) object, AF_INET, 0, FALSE)) { + nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP4 route %s", to_string_ip4_route ((struct rtnl_route *) object)); + return; + } if (init_ip4_route (&route, (struct rtnl_route *) object)) g_signal_emit_by_name (platform, sig, route.ifindex, &route, change_type, reason); } @@ -1614,6 +1680,10 @@ announce_object (NMPlatform *platform, const struct nl_object *object, NMPlatfor { NMPlatformIP6Route route; + if (!_route_match ((struct rtnl_route *) object, AF_INET6, 0, FALSE)) { + nm_log_dbg (LOGD_PLATFORM, "skip announce unmatching IP6 route %s", to_string_ip6_route ((struct rtnl_route *) object)); + return; + } if (init_ip6_route (&route, (struct rtnl_route *) object)) g_signal_emit_by_name (platform, sig, route.ifindex, &route, change_type, reason); } @@ -1721,15 +1791,14 @@ add_object (NMPlatform *platform, struct nl_object *obj) /* Decreases the reference count if @obj for convenience */ static gboolean -delete_object (NMPlatform *platform, struct nl_object *obj, gboolean do_refresh_object) +delete_object (NMPlatform *platform, struct nl_object *object, gboolean do_refresh_object) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); - auto_nl_object struct nl_object *obj_cleanup = obj; - struct nl_object *object = obj; int object_type; int nle; + gboolean result = FALSE; - object_type = object_type_from_nl_object (obj); + object_type = object_type_from_nl_object (object); g_return_val_if_fail (object_type != OBJECT_TYPE_UNKNOWN, FALSE); switch (object_type) { @@ -1772,14 +1841,18 @@ delete_object (NMPlatform *platform, struct nl_object *obj, gboolean do_refresh_ goto DEFAULT; DEFAULT: default: - error ("Netlink error deleting %s: %s (%d)", to_string_object (platform, obj), nl_geterror (nle), nle); - return FALSE; + error ("Netlink error deleting %s: %s (%d)", to_string_object (platform, object), nl_geterror (nle), nle); + goto out; } if (do_refresh_object) refresh_object (platform, object, TRUE, NM_PLATFORM_REASON_INTERNAL); - return TRUE; + result = TRUE; + +out: + nl_object_put (object); + return result; } static void @@ -1807,6 +1880,33 @@ _rtnl_addr_timestamps_equal_fuzzy (guint32 ts1, guint32 ts2) return diff <= 2; } +static gboolean +nm_nl_object_diff (ObjectType type, struct nl_object *_a, struct nl_object *_b) +{ + if (nl_object_diff (_a, _b)) { + /* libnl thinks objects are different*/ + return TRUE; + } + + if (type == OBJECT_TYPE_IP4_ADDRESS || type == OBJECT_TYPE_IP6_ADDRESS) { + struct rtnl_addr *a = (struct rtnl_addr *) _a; + struct rtnl_addr *b = (struct rtnl_addr *) _b; + + /* libnl nl_object_diff() ignores differences in timestamp. Let's care about + * them (if they are large enough). + * + * Note that these valid and preferred timestamps are absolute, after + * _rtnl_addr_hack_lifetimes_rel_to_abs(). */ + if ( !_rtnl_addr_timestamps_equal_fuzzy (rtnl_addr_get_preferred_lifetime (a), + rtnl_addr_get_preferred_lifetime (b)) + || !_rtnl_addr_timestamps_equal_fuzzy (rtnl_addr_get_valid_lifetime (a), + rtnl_addr_get_valid_lifetime (b))) + return TRUE; + } + + return FALSE; +} + /* This function does all the magic to avoid race conditions caused * by concurrent usage of synchronous commands and an asynchronous cache. This * might be a nice future addition to libnl but it requires to do all operations @@ -1912,24 +2012,9 @@ event_notification (struct nl_msg *msg, gpointer user_data) * This also catches notifications for internal addition or change, unless * another action occured very soon after it. */ - if (!nl_object_diff (kernel_object, cached_object)) { - if (type == OBJECT_TYPE_IP4_ADDRESS || type == OBJECT_TYPE_IP6_ADDRESS) { - struct rtnl_addr *c = (struct rtnl_addr *) cached_object; - struct rtnl_addr *k = (struct rtnl_addr *) kernel_object; - - /* libnl nl_object_diff() ignores differences in timestamp. Let's care about - * them (if they are large enough). - * - * Note that these valid and preferred timestamps are absolute, after - * _rtnl_addr_hack_lifetimes_rel_to_abs(). */ - if ( _rtnl_addr_timestamps_equal_fuzzy (rtnl_addr_get_preferred_lifetime (c), - rtnl_addr_get_preferred_lifetime (k)) - && _rtnl_addr_timestamps_equal_fuzzy (rtnl_addr_get_valid_lifetime (c), - rtnl_addr_get_valid_lifetime (k))) - return NL_OK; - } else - return NL_OK; - } + if (!nm_nl_object_diff (type, kernel_object, cached_object)) + return NL_OK; + /* Handle external change */ nl_cache_remove (cached_object); nle = nl_cache_add (cache, kernel_object); @@ -2133,7 +2218,7 @@ link_get_all (NMPlatform *platform) } static gboolean -_nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *link) +_nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *l) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); auto_nl_object struct rtnl_link *rtnllink = NULL; @@ -2141,7 +2226,7 @@ _nm_platform_link_get (NMPlatform *platform, int ifindex, NMPlatformLink *link) rtnllink = rtnl_link_get (priv->link_cache, ifindex); if (rtnllink) { if (link_is_announceable (platform, rtnllink)) { - if (init_link (platform, link, rtnllink)) + if (init_link (platform, l, rtnllink)) return TRUE; } } @@ -2166,7 +2251,7 @@ static gboolean link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *address, size_t address_len) { int r; - struct nl_object *link; + struct nl_object *l; if (type == NM_LINK_TYPE_BOND) { /* When the kernel loads the bond module, either via explicit modprobe @@ -2184,15 +2269,15 @@ link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *a debug ("link: add link '%s' of type '%s' (%d)", name, type_to_string (type), (int) type); - link = build_rtnl_link (0, name, type); + l = build_rtnl_link (0, name, type); g_assert ( (address != NULL) ^ (address_len == 0) ); if (address) { auto_nl_addr struct nl_addr *nladdr = _nm_nl_addr_build (AF_LLC, address, address_len); - rtnl_link_set_addr ((struct rtnl_link *) link, nladdr); + rtnl_link_set_addr ((struct rtnl_link *) l, nladdr); } - return add_object (platform, link); + return add_object (platform, l); } static struct rtnl_link * @@ -2383,6 +2468,46 @@ link_set_noarp (NMPlatform *platform, int ifindex) return link_change_flags (platform, ifindex, IFF_NOARP, TRUE); } +static gboolean +link_get_user_ipv6ll_enabled (NMPlatform *platform, int ifindex) +{ +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + + if (priv->support_user_ipv6ll > 0) { + auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex); + uint8_t mode = 0; + + if (rtnllink) { + if (rtnl_link_inet6_get_addr_gen_mode (rtnllink, &mode) != 0) { + /* Default to "disabled" on error */ + return FALSE; + } + return mode == IN6_ADDR_GEN_MODE_NONE; + } + } +#endif + return FALSE; +} + +static gboolean +link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled) +{ +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + if (check_support_user_ipv6ll (platform)) { + auto_nl_object struct rtnl_link *change = _nm_rtnl_link_alloc (ifindex, NULL); + guint8 mode = enabled ? IN6_ADDR_GEN_MODE_NONE : IN6_ADDR_GEN_MODE_EUI64; + char buf[32]; + + rtnl_link_inet6_set_addr_gen_mode (change, mode); + debug ("link: change %d: set IPv6 address generation mode to %s", + ifindex, rtnl_link_inet6_addrgenmode2str (mode, buf, sizeof (buf))); + return link_change (platform, ifindex, change); + } +#endif + return FALSE; +} + static gboolean supports_ethtool_carrier_detect (const char *ifname) { @@ -2455,7 +2580,7 @@ link_supports_vlans (NMPlatform *platform, int ifindex) { auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex); const char *name = nm_platform_link_get_name (ifindex); - auto_g_free struct ethtool_gfeatures *features = NULL; + gs_free struct ethtool_gfeatures *features = NULL; int idx, block, bit, size; /* Only ARPHRD_ETHER links can possibly support VLANs. */ @@ -2494,7 +2619,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size rtnl_link_set_addr (change, nladdr); if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { - char *mac = nm_utils_hwaddr_ntoa_len (address, length); + char *mac = nm_utils_hwaddr_ntoa (address, length); debug ("link: change %d: address %s (%lu bytes)", ifindex, mac, (unsigned long) length); g_free (mac); @@ -2508,13 +2633,23 @@ link_get_address (NMPlatform *platform, int ifindex, size_t *length) { auto_nl_object struct rtnl_link *rtnllink = link_get (platform, ifindex); struct nl_addr *nladdr; - - nladdr = rtnllink ? rtnl_link_get_addr (rtnllink) : NULL; + size_t l = 0; + gconstpointer a = NULL; + + if (rtnllink && + (nladdr = rtnl_link_get_addr (rtnllink))) { + l = nl_addr_get_len (nladdr); + if (l > NM_UTILS_HWADDR_LEN_MAX) { + if (length) + *length = 0; + g_return_val_if_reached (NULL); + } else if (l > 0) + a = nl_addr_get_binary_addr (nladdr); + } if (length) - *length = nladdr ? nl_addr_get_len (nladdr) : 0; - - return nladdr ? nl_addr_get_binary_addr (nladdr) : NULL; + *length = l; + return a; } static gboolean @@ -2667,7 +2802,7 @@ link_option_path (int master, const char *category, const char *option) static gboolean link_set_option (int master, const char *category, const char *option, const char *value) { - auto_g_free char *path = link_option_path (master, category, option); + gs_free char *path = link_option_path (master, category, option); return path && nm_platform_sysctl_set (path, value); } @@ -2675,7 +2810,7 @@ link_set_option (int master, const char *category, const char *option, const cha static char * link_get_option (int master, const char *category, const char *option) { - auto_g_free char *path = link_option_path (master, category, option); + gs_free char *path = link_option_path (master, category, option); return path ? nm_platform_sysctl_get (path) : NULL; } @@ -2754,7 +2889,7 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key) g_free (path); if (success) { - auto_g_free char *ifname = g_strdup_printf ("%s.%04x", parent_name, p_key); + gs_free char *ifname = g_strdup_printf ("%s.%04x", parent_name, p_key); auto_nl_object struct rtnl_link *rtnllink = _nm_rtnl_link_alloc (0, ifname); success = refresh_object (platform, (struct nl_object *) rtnllink, FALSE, NM_PLATFORM_REASON_INTERNAL); @@ -2767,7 +2902,7 @@ static gboolean veth_get_properties (NMPlatform *platform, int ifindex, NMPlatformVethProperties *props) { const char *ifname; - auto_g_free struct ethtool_stats *stats = NULL; + gs_free struct ethtool_stats *stats = NULL; int peer_ifindex_stat; ifname = nm_platform_link_get_name (ifindex); @@ -2841,7 +2976,7 @@ tun_get_properties (NMPlatform *platform, int ifindex, NMPlatformTunProperties * #ifndef IFF_MULTI_QUEUE const int IFF_MULTI_QUEUE = 0x0100; #endif - props->mode = ((flags & TUN_TYPE_MASK) == TUN_TUN_DEV) ? "tun" : "tap"; + props->mode = ((flags & (IFF_TUN | IFF_TAP)) == IFF_TUN) ? "tun" : "tap"; props->no_pi = !!(flags & IFF_NO_PI); props->vnet_hdr = !!(flags & IFF_VNET_HDR); props->multi_queue = !!(flags & IFF_MULTI_QUEUE); @@ -2947,6 +3082,13 @@ macvlan_get_properties (NMPlatform *platform, int ifindex, NMPlatformMacvlanProp #undef IFLA_VXLAN_MAX #define IFLA_VXLAN_MAX IFLA_VXLAN_LOCAL6 +/* older kernel header might not contain 'struct ifla_vxlan_port_range'. + * Redefine it. */ +struct nm_ifla_vxlan_port_range { + guint16 low; + guint16 high; +}; + static const struct nla_policy vxlan_info_policy[IFLA_VXLAN_MAX + 1] = { [IFLA_VXLAN_ID] = { .type = NLA_U32 }, [IFLA_VXLAN_GROUP] = { .type = NLA_U32 }, @@ -2962,7 +3104,7 @@ static const struct nla_policy vxlan_info_policy[IFLA_VXLAN_MAX + 1] = { [IFLA_VXLAN_AGEING] = { .type = NLA_U32 }, [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 }, [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_UNSPEC, - .minlen = sizeof (struct ifla_vxlan_port_range) }, + .minlen = sizeof (struct nm_ifla_vxlan_port_range) }, [IFLA_VXLAN_PROXY] = { .type = NLA_U8 }, [IFLA_VXLAN_RSC] = { .type = NLA_U8 }, [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 }, @@ -2975,7 +3117,7 @@ vxlan_info_data_parser (struct nlattr *info_data, gpointer parser_data) { NMPlatformVxlanProperties *props = parser_data; struct nlattr *tb[IFLA_VXLAN_MAX + 1]; - struct ifla_vxlan_port_range *range; + struct nm_ifla_vxlan_port_range *range; int err; err = nla_parse_nested (tb, IFLA_VXLAN_MAX, info_data, @@ -2985,8 +3127,10 @@ vxlan_info_data_parser (struct nlattr *info_data, gpointer parser_data) memset (props, 0, sizeof (*props)); - props->parent_ifindex = tb[IFLA_VXLAN_LINK] ? nla_get_u32 (tb[IFLA_VXLAN_LINK]) : 0; - props->id = nla_get_u32 (tb[IFLA_VXLAN_ID]); + if (tb[IFLA_VXLAN_LINK]) + props->parent_ifindex = nla_get_u32 (tb[IFLA_VXLAN_LINK]); + if (tb[IFLA_VXLAN_ID]) + props->id = nla_get_u32 (tb[IFLA_VXLAN_ID]); if (tb[IFLA_VXLAN_GROUP]) props->group = nla_get_u32 (tb[IFLA_VXLAN_GROUP]); if (tb[IFLA_VXLAN_LOCAL]) @@ -2996,21 +3140,34 @@ vxlan_info_data_parser (struct nlattr *info_data, gpointer parser_data) if (tb[IFLA_VXLAN_LOCAL6]) memcpy (&props->local6, nla_data (tb[IFLA_VXLAN_LOCAL6]), sizeof (props->local6)); - props->ageing = nla_get_u32 (tb[IFLA_VXLAN_AGEING]); - props->limit = nla_get_u32 (tb[IFLA_VXLAN_LIMIT]); - props->tos = nla_get_u8 (tb[IFLA_VXLAN_TOS]); - props->ttl = nla_get_u8 (tb[IFLA_VXLAN_TTL]); - - props->dst_port = nla_get_u16 (tb[IFLA_VXLAN_PORT]); - range = nla_data (tb[IFLA_VXLAN_PORT_RANGE]); - props->src_port_min = range->low; - props->src_port_max = range->high; + if (tb[IFLA_VXLAN_AGEING]) + props->ageing = nla_get_u32 (tb[IFLA_VXLAN_AGEING]); + if (tb[IFLA_VXLAN_LIMIT]) + props->limit = nla_get_u32 (tb[IFLA_VXLAN_LIMIT]); + if (tb[IFLA_VXLAN_TOS]) + props->tos = nla_get_u8 (tb[IFLA_VXLAN_TOS]); + if (tb[IFLA_VXLAN_TTL]) + props->ttl = nla_get_u8 (tb[IFLA_VXLAN_TTL]); + + if (tb[IFLA_VXLAN_PORT]) + props->dst_port = nla_get_u16 (tb[IFLA_VXLAN_PORT]); + + if (tb[IFLA_VXLAN_PORT_RANGE]) { + range = nla_data (tb[IFLA_VXLAN_PORT_RANGE]); + props->src_port_min = range->low; + props->src_port_max = range->high; + } - props->learning = !!nla_get_u8 (tb[IFLA_VXLAN_LEARNING]); - props->proxy = !!nla_get_u8 (tb[IFLA_VXLAN_PROXY]); - props->rsc = !!nla_get_u8 (tb[IFLA_VXLAN_RSC]); - props->l2miss = !!nla_get_u8 (tb[IFLA_VXLAN_L2MISS]); - props->l3miss = !!nla_get_u8 (tb[IFLA_VXLAN_L3MISS]); + if (tb[IFLA_VXLAN_LEARNING]) + props->learning = !!nla_get_u8 (tb[IFLA_VXLAN_LEARNING]); + if (tb[IFLA_VXLAN_PROXY]) + props->proxy = !!nla_get_u8 (tb[IFLA_VXLAN_PROXY]); + if (tb[IFLA_VXLAN_RSC]) + props->rsc = !!nla_get_u8 (tb[IFLA_VXLAN_RSC]); + if (tb[IFLA_VXLAN_L2MISS]) + props->l2miss = !!nla_get_u8 (tb[IFLA_VXLAN_L2MISS]); + if (tb[IFLA_VXLAN_L3MISS]) + props->l3miss = !!nla_get_u8 (tb[IFLA_VXLAN_L3MISS]); return 0; } @@ -3131,7 +3288,7 @@ wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabiliti } static gboolean -wifi_get_bssid (NMPlatform *platform, int ifindex, struct ether_addr *bssid) +wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) { WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); @@ -3244,14 +3401,14 @@ mesh_set_channel (NMPlatform *platform, int ifindex, guint32 channel) } static gboolean -mesh_set_ssid (NMPlatform *platform, int ifindex, const GByteArray *ssid) +mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) { WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); if (!wifi_data) return FALSE; - return wifi_utils_set_mesh_ssid (wifi_data, ssid); + return wifi_utils_set_mesh_ssid (wifi_data, ssid, len); } static gboolean @@ -3287,7 +3444,7 @@ _address_match (struct rtnl_addr *addr, int family, int ifindex) g_return_val_if_fail (addr, FALSE); return rtnl_addr_get_family (addr) == family && - rtnl_addr_get_ifindex (addr) == ifindex; + (ifindex == 0 || rtnl_addr_get_ifindex (addr) == ifindex); } static GArray * @@ -3455,9 +3612,9 @@ ip6_address_add (NMPlatform *platform, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) { - return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0, NULL), TRUE); + return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, peer_address ? &peer_address : NULL, plen, 0, 0, 0, NULL), TRUE); } static gboolean @@ -3487,10 +3644,53 @@ ip6_address_exists (NMPlatform *platform, int ifindex, struct in6_addr addr, int return ip_address_exists (platform, AF_INET6, ifindex, &addr, plen); } +static gboolean +ip4_check_reinstall_device_route (NMPlatform *platform, int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + NMPlatformIP4Address addr_candidate; + NMPlatformIP4Route route_candidate; + struct nl_object *object; + guint32 device_network; + + for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) { + if (_address_match ((struct rtnl_addr *) object, AF_INET, 0)) { + if (init_ip4_address (&addr_candidate, (struct rtnl_addr *) object)) + if ( addr_candidate.plen == address->plen + && addr_candidate.address == address->address) { + /* If we already have the same address installed on any interface, + * we back off. + * Perform this check first, as we expect to have significantly less + * addresses to search. */ + return FALSE; + } + } + } + + device_network = nm_utils_ip4_address_clear_host_address (address->address, address->plen); + + for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) { + if (_route_match ((struct rtnl_route *) object, AF_INET, 0, TRUE)) { + if (init_ip4_route (&route_candidate, (struct rtnl_route *) object)) { + if ( route_candidate.network == device_network + && route_candidate.plen == address->plen + && ( route_candidate.metric == 0 + || route_candidate.metric == device_route_metric)) { + /* There is already any route with metric 0 or the metric we want to install + * for the same subnet. */ + return FALSE; + } + } + } + } + + return TRUE; +} + /******************************************************************/ static gboolean -_route_match (struct rtnl_route *rtnlroute, int family, int ifindex) +_route_match (struct rtnl_route *rtnlroute, int family, int ifindex, gboolean include_proto_kernel) { struct rtnl_nexthop *nexthop; @@ -3498,31 +3698,42 @@ _route_match (struct rtnl_route *rtnlroute, int family, int ifindex) if (rtnl_route_get_type (rtnlroute) != RTN_UNICAST || rtnl_route_get_table (rtnlroute) != RT_TABLE_MAIN || - rtnl_route_get_protocol (rtnlroute) == RTPROT_KERNEL || + (!include_proto_kernel && rtnl_route_get_protocol (rtnlroute) == RTPROT_KERNEL) || rtnl_route_get_family (rtnlroute) != family || - rtnl_route_get_nnexthops (rtnlroute) != 1) + rtnl_route_get_nnexthops (rtnlroute) != 1 || + rtnl_route_get_flags (rtnlroute) & RTM_F_CLONED) return FALSE; + if (ifindex == 0) + return TRUE; + nexthop = rtnl_route_nexthop_n (rtnlroute, 0); return rtnl_route_nh_get_ifindex (nexthop) == ifindex; } static GArray * -ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) +ip4_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); GArray *routes; NMPlatformIP4Route route; struct nl_object *object; + g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL); + routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route)); for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) { - if (_route_match ((struct rtnl_route *) object, AF_INET, ifindex)) { - if (init_ip4_route (&route, (struct rtnl_route *) object)) { - if (route.plen != 0 || include_default) - g_array_append_val (routes, route); + if (_route_match ((struct rtnl_route *) object, AF_INET, ifindex, FALSE)) { + if (_rtnl_route_is_default ((struct rtnl_route *) object)) { + if (mode == NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT) + continue; + } else { + if (mode == NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT) + continue; } + if (init_ip4_route (&route, (struct rtnl_route *) object)) + g_array_append_val (routes, route); } } @@ -3530,21 +3741,28 @@ ip4_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) } static GArray * -ip6_route_get_all (NMPlatform *platform, int ifindex, gboolean include_default) +ip6_route_get_all (NMPlatform *platform, int ifindex, NMPlatformGetRouteMode mode) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); GArray *routes; NMPlatformIP6Route route; struct nl_object *object; + g_return_val_if_fail (NM_IN_SET (mode, NM_PLATFORM_GET_ROUTE_MODE_ALL, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT), NULL); + routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP6Route)); for (object = nl_cache_get_first (priv->route_cache); object; object = nl_cache_get_next (object)) { - if (_route_match ((struct rtnl_route *) object, AF_INET6, ifindex)) { - if (init_ip6_route (&route, (struct rtnl_route *) object)) { - if (route.plen != 0 || include_default) - g_array_append_val (routes, route); + if (_route_match ((struct rtnl_route *) object, AF_INET6, ifindex, FALSE)) { + if (_rtnl_route_is_default ((struct rtnl_route *) object)) { + if (mode == NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT) + continue; + } else { + if (mode == NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT) + continue; } + if (init_ip6_route (&route, (struct rtnl_route *) object)) + g_array_append_val (routes, route); } } @@ -3570,9 +3788,10 @@ clear_host_address (int family, const void *network, int plen, void *dst) } static struct nl_object * -build_rtnl_route (int family, int ifindex, NMPlatformSource source, +build_rtnl_route (int family, int ifindex, NMIPConfigSource source, gconstpointer network, int plen, gconstpointer gateway, - int metric, int mss) + gconstpointer pref_src, + guint32 metric, guint32 mss) { guint32 network_clean[4]; struct rtnl_route *rtnlroute; @@ -3581,6 +3800,7 @@ build_rtnl_route (int family, int ifindex, NMPlatformSource source, /* Workaround a libnl bug by using zero destination address length for default routes */ auto_nl_addr struct nl_addr *dst = NULL; auto_nl_addr struct nl_addr *gw = gateway ? _nm_nl_addr_build (family, gateway, addrlen) : NULL; + auto_nl_addr struct nl_addr *pref_src_nl = pref_src ? _nm_nl_addr_build (family, pref_src, addrlen) : NULL; /* There seem to be problems adding a route with non-zero host identifier. * Adding IPv6 routes is simply ignored, without error message. @@ -3602,6 +3822,8 @@ build_rtnl_route (int family, int ifindex, NMPlatformSource source, rtnl_route_nh_set_ifindex (nexthop, ifindex); if (gw && !nl_addr_iszero (gw)) rtnl_route_nh_set_gateway (nexthop, gw); + if (pref_src_nl) + rtnl_route_set_pref_src (rtnlroute, pref_src_nl); rtnl_route_add_nexthop (rtnlroute, nexthop); if (mss > 0) @@ -3611,23 +3833,23 @@ build_rtnl_route (int family, int ifindex, NMPlatformSource source, } static gboolean -ip4_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, +ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, in_addr_t network, int plen, in_addr_t gateway, - int metric, int mss) + guint32 pref_src, guint32 metric, guint32 mss) { - return add_object (platform, build_rtnl_route (AF_INET, ifindex, source, &network, plen, &gateway, metric, mss)); + return add_object (platform, build_rtnl_route (AF_INET, ifindex, source, &network, plen, &gateway, pref_src ? &pref_src : NULL, metric, mss)); } static gboolean -ip6_route_add (NMPlatform *platform, int ifindex, NMPlatformSource source, +ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, - int metric, int mss) + guint32 metric, guint32 mss) { - return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, metric, mss)); + return add_object (platform, build_rtnl_route (AF_INET6, ifindex, source, &network, plen, &gateway, NULL, metric, mss)); } static struct rtnl_route * -route_search_cache (struct nl_cache *cache, int family, int ifindex, const void *network, int plen, int metric) +route_search_cache (struct nl_cache *cache, int family, int ifindex, const void *network, int plen, guint32 metric) { guint32 network_clean[4], dst_clean[4]; struct nl_object *object; @@ -3638,7 +3860,7 @@ route_search_cache (struct nl_cache *cache, int family, int ifindex, const void struct nl_addr *dst; struct rtnl_route *rtnlroute = (struct rtnl_route *) object; - if (!_route_match (rtnlroute, family, ifindex)) + if (!_route_match (rtnlroute, family, ifindex, FALSE)) continue; if (metric && metric != rtnl_route_get_priority (rtnlroute)) @@ -3676,11 +3898,11 @@ refresh_route (NMPlatform *platform, int family, int ifindex, const void *networ } static gboolean -ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, int metric) +ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) { in_addr_t gateway = 0; struct rtnl_route *cached_object; - struct nl_object *route = build_rtnl_route (AF_INET, ifindex, NM_PLATFORM_SOURCE_UNKNOWN, &network, plen, &gateway, metric, 0); + struct nl_object *route = build_rtnl_route (AF_INET, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN, &network, plen, &gateway, NULL, metric, 0); uint8_t scope = RT_SCOPE_NOWHERE; struct nl_cache *cache; @@ -3736,20 +3958,20 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen } static gboolean -ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, int metric) +ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { struct in6_addr gateway = IN6ADDR_ANY_INIT; - return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_PLATFORM_SOURCE_UNKNOWN ,&network, plen, &gateway, metric, 0), FALSE) && + return delete_object (platform, build_rtnl_route (AF_INET6, ifindex, NM_IP_CONFIG_SOURCE_UNKNOWN ,&network, plen, &gateway, NULL, metric, 0), FALSE) && refresh_route (platform, AF_INET6, ifindex, &network, plen, metric); } static gboolean -ip_route_exists (NMPlatform *platform, int family, int ifindex, gpointer network, int plen, int metric) +ip_route_exists (NMPlatform *platform, int family, int ifindex, gpointer network, int plen, guint32 metric) { auto_nl_object struct nl_object *object = build_rtnl_route (family, ifindex, - NM_PLATFORM_SOURCE_UNKNOWN, - network, plen, NULL, metric, 0); + NM_IP_CONFIG_SOURCE_UNKNOWN, + network, plen, NULL, NULL, metric, 0); struct nl_cache *cache = choose_cache (platform, object); auto_nl_object struct nl_object *cached_object = nl_cache_search (cache, object); @@ -3759,19 +3981,119 @@ ip_route_exists (NMPlatform *platform, int family, int ifindex, gpointer network } static gboolean -ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, int metric) +ip4_route_exists (NMPlatform *platform, int ifindex, in_addr_t network, int plen, guint32 metric) { return ip_route_exists (platform, AF_INET, ifindex, &network, plen, metric); } static gboolean -ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, int metric) +ip6_route_exists (NMPlatform *platform, int ifindex, struct in6_addr network, int plen, guint32 metric) { return ip_route_exists (platform, AF_INET6, ifindex, &network, plen, metric); } /******************************************************************/ +/* Initialize the link cache while ensuring all links are of AF_UNSPEC, + * family (even though the kernel might set AF_BRIDGE for bridges). + * See also: _nl_link_family_unset() */ +static void +init_link_cache (NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + struct nl_object *object = NULL; + + rtnl_link_alloc_cache (priv->nlh, AF_UNSPEC, &priv->link_cache); + + do { + for (object = nl_cache_get_first (priv->link_cache); object; object = nl_cache_get_next (object)) { + if (rtnl_link_get_family ((struct rtnl_link *)object) != AF_UNSPEC) + break; + } + + if (object) { + /* A non-AF_UNSPEC object encoutnered */ + struct nl_object *existing; + + nl_object_get (object); + nl_cache_remove (object); + rtnl_link_set_family ((struct rtnl_link *)object, AF_UNSPEC); + existing = nl_cache_search (priv->link_cache, object); + if (existing) + nl_object_put (existing); + else + nl_cache_add (priv->link_cache, object); + nl_object_put (object); + } + } while (object); +} + +/* Calls announce_object with appropriate arguments for all objects + * which are not coherent between old and new caches and deallocates + * the old cache. */ +static void +cache_announce_changes (NMPlatform *platform, struct nl_cache *new, struct nl_cache *old) +{ + struct nl_object *object; + + if (!old) + return; + + for (object = nl_cache_get_first (new); object; object = nl_cache_get_next (object)) { + struct nl_object *cached_object = nm_nl_cache_search (old, object); + + if (cached_object) { + ObjectType type = object_type_from_nl_object (object); + if (nm_nl_object_diff (type, object, cached_object)) + announce_object (platform, object, NM_PLATFORM_SIGNAL_CHANGED, NM_PLATFORM_REASON_EXTERNAL); + nl_object_put (cached_object); + } else + announce_object (platform, object, NM_PLATFORM_SIGNAL_ADDED, NM_PLATFORM_REASON_EXTERNAL); + } + for (object = nl_cache_get_first (old); object; object = nl_cache_get_next (object)) { + struct nl_object *cached_object = nm_nl_cache_search (new, object); + if (cached_object) + nl_object_put (cached_object); + else + announce_object (platform, object, NM_PLATFORM_SIGNAL_REMOVED, NM_PLATFORM_REASON_EXTERNAL); + } + + nl_cache_free (old); +} + +/* Creates and populates the netlink object caches. Called upon platform init and + * when we run out of sync (out of buffer space, netlink congestion control). In case + * the caches already exist, it finds changed, added and removed objects, announces + * them and destroys the old caches. */ +static void +cache_repopulate_all (NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + struct nl_cache *old_link_cache = priv->link_cache; + struct nl_cache *old_address_cache = priv->address_cache; + struct nl_cache *old_route_cache = priv->route_cache; + struct nl_object *object; + + debug ("platform: %spopulate platform cache", old_link_cache ? "re" : ""); + + /* Allocate new netlink caches */ + init_link_cache (platform); + rtnl_addr_alloc_cache (priv->nlh, &priv->address_cache); + rtnl_route_alloc_cache (priv->nlh, AF_UNSPEC, 0, &priv->route_cache); + g_assert (priv->link_cache && priv->address_cache && priv->route_cache); + + for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) { + _rtnl_addr_hack_lifetimes_rel_to_abs ((struct rtnl_addr *) object); + } + + /* Make sure all changes we've missed are announced. */ + cache_announce_changes (platform, priv->link_cache, old_link_cache); + cache_announce_changes (platform, priv->address_cache, old_address_cache); + cache_announce_changes (platform, priv->route_cache, old_route_cache); +} + +/******************************************************************/ + #define EVENT_CONDITIONS ((GIOCondition) (G_IO_IN | G_IO_PRI)) #define ERROR_CONDITIONS ((GIOCondition) (G_IO_ERR | G_IO_NVAL)) #define DISCONNECT_CONDITIONS ((GIOCondition) (G_IO_HUP)) @@ -3798,7 +4120,8 @@ event_handler (GIOChannel *channel, GIOCondition io_condition, gpointer user_data) { - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (user_data); + NMPlatform *platform = NM_PLATFORM (user_data); + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); int nle; nle = nl_recvmsgs_default (priv->nlh_event); @@ -3810,6 +4133,17 @@ event_handler (GIOChannel *channel, * and can happen easily. */ debug ("Uncritical failure to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); break; + case -NLE_NOMEM: + warning ("Too many netlink events. Need to resynchronize platform cache"); + /* Drain the event queue, we've lost events and are out of sync anyway and we'd + * like to free up some space. We'll read in the status synchronously. */ + nl_socket_modify_cb (priv->nlh_event, NL_CB_VALID, NL_CB_DEFAULT, NULL, NULL); + do { + nle = nl_recvmsgs_default (priv->nlh_event); + } while (nle != -NLE_AGAIN); + nl_socket_modify_cb (priv->nlh_event, NL_CB_VALID, NL_CB_CUSTOM, event_notification, user_data); + cache_repopulate_all (platform); + break; default: error ("Failed to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); break; @@ -3841,6 +4175,12 @@ setup_socket (gboolean event, gpointer user_data) nle = nl_socket_set_passcred (sock, 1); g_assert (!nle); + /* No blocking for event socket, so that we can drain it safely. */ + if (event) { + nle = nl_socket_set_nonblocking (sock); + g_assert (!nle); + } + return sock; } @@ -3979,7 +4319,9 @@ setup (NMPlatform *platform) int channel_flags; gboolean status; int nle; +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE struct nl_object *object; +#endif /* Initialize netlink socket for requests */ priv->nlh = setup_socket (FALSE, platform); @@ -4015,14 +4357,25 @@ setup (NMPlatform *platform) (EVENT_CONDITIONS | ERROR_CONDITIONS | DISCONNECT_CONDITIONS), event_handler, platform); - /* Allocate netlink caches */ - rtnl_link_alloc_cache (priv->nlh, AF_UNSPEC, &priv->link_cache); - rtnl_addr_alloc_cache (priv->nlh, &priv->address_cache); - rtnl_route_alloc_cache (priv->nlh, AF_UNSPEC, 0, &priv->route_cache); - g_assert (priv->link_cache && priv->address_cache && priv->route_cache); + cache_repopulate_all (platform); - for (object = nl_cache_get_first (priv->address_cache); object; object = nl_cache_get_next (object)) - _rtnl_addr_hack_lifetimes_rel_to_abs ((struct rtnl_addr *) object); +#if HAVE_LIBNL_INET6_ADDR_GEN_MODE + /* Initial check for user IPv6LL support once the link cache is allocated + * and filled. If there are no links in the cache yet then we'll check + * when a new link shows up in announce_object(). + */ + object = nl_cache_get_first (priv->link_cache); + if (object) { + uint8_t mode; + + if (rtnl_link_inet6_get_addr_gen_mode ((struct rtnl_link *) object, &mode) == 0) + priv->support_user_ipv6ll = 1; + else + priv->support_user_ipv6ll = -1; + } +#else + priv->support_user_ipv6ll = -1; +#endif /* Set up udev monitoring */ priv->udev_client = g_udev_client_new (udev_subsys); @@ -4111,6 +4464,9 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_is_connected = link_is_connected; platform_class->link_uses_arp = link_uses_arp; + platform_class->link_get_user_ipv6ll_enabled = link_get_user_ipv6ll_enabled; + platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_get_address = link_get_address; platform_class->link_set_address = link_set_address; platform_class->link_get_mtu = link_get_mtu; @@ -4167,6 +4523,8 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->ip4_address_exists = ip4_address_exists; platform_class->ip6_address_exists = ip6_address_exists; + platform_class->ip4_check_reinstall_device_route = ip4_check_reinstall_device_route; + platform_class->ip4_route_get_all = ip4_route_get_all; platform_class->ip6_route_get_all = ip6_route_get_all; platform_class->ip4_route_add = ip4_route_add; @@ -4177,4 +4535,5 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->ip6_route_exists = ip6_route_exists; platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags; + platform_class->check_support_user_ipv6ll = check_support_user_ipv6ll; } diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index 53ea75e6..6f2c1993 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -18,8 +18,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#ifndef NM_LINUX_PLATFORM_H -#define NM_LINUX_PLATFORM_H +#ifndef __NETWORKMANAGER_LINUX_PLATFORM_H__ +#define __NETWORKMANAGER_LINUX_PLATFORM_H__ #include "nm-platform.h" @@ -46,4 +46,4 @@ GType nm_linux_platform_get_type (void); void nm_linux_platform_setup (void); -#endif /* NM_LINUX_PLATFORM_H */ +#endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 542b0faa..14fc44c5 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -18,6 +18,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -26,6 +28,7 @@ #include #include +#include "gsystem-local-alloc.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-platform.h" @@ -215,6 +218,21 @@ nm_platform_check_support_kernel_extended_ifa_flags () return klass->check_support_kernel_extended_ifa_flags (platform); } +gboolean +nm_platform_check_support_user_ipv6ll (void) +{ + static int supported = -1; + + g_return_val_if_fail (NM_IS_PLATFORM (platform), FALSE); + + if (!klass->check_support_user_ipv6ll) + return FALSE; + + if (supported < 0) + supported = klass->check_support_user_ipv6ll (platform) ? 1 : 0; + return !!supported; +} + /******************************************************************/ /** @@ -729,6 +747,52 @@ nm_platform_link_uses_arp (int ifindex) return klass->link_uses_arp (platform, ifindex); } +/** + * nm_platform_link_get_user_ip6vll_enabled: + * @ifindex: Interface index + * + * Check whether NM handles IPv6LL address creation for the link. If the + * platform or OS doesn't support changing the IPv6LL address mode, this call + * will fail and return %FALSE. + * + * Returns: %TRUE if NM handles the IPv6LL address for @ifindex + */ +gboolean +nm_platform_link_get_user_ipv6ll_enabled (int ifindex) +{ + reset_error (); + + g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail (klass->check_support_user_ipv6ll, FALSE); + + if (klass->link_get_user_ipv6ll_enabled) + return klass->link_get_user_ipv6ll_enabled (platform, ifindex); + return FALSE; +} + +/** + * nm_platform_link_set_user_ip6vll_enabled: + * @ifindex: Interface index + * + * Set whether NM handles IPv6LL address creation for the link. If the + * platform or OS doesn't support changing the IPv6LL address mode, this call + * will fail and return %FALSE. + * + * Returns: %TRUE if the operation was successful, %FALSE if it failed. + */ +gboolean +nm_platform_link_set_user_ipv6ll_enabled (int ifindex, gboolean enabled) +{ + reset_error (); + + g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail (klass->check_support_user_ipv6ll, FALSE); + + if (klass->link_set_user_ipv6ll_enabled) + return klass->link_set_user_ipv6ll_enabled (platform, ifindex, enabled); + return FALSE; +} + /** * nm_platform_link_set_address: * @ifindex: Interface index @@ -877,7 +941,7 @@ nm_platform_link_set_mtu (int ifindex, guint32 mtu) g_return_val_if_fail (mtu > 0, FALSE); g_return_val_if_fail (klass->link_set_mtu, FALSE); - debug ("link: setting '%s' (%d) mtu %d", nm_platform_link_get_name (ifindex), ifindex, mtu); + debug ("link: setting '%s' (%d) mtu %"G_GUINT32_FORMAT, nm_platform_link_get_name (ifindex), ifindex, mtu); return klass->link_set_mtu (platform, ifindex, mtu); } @@ -1051,7 +1115,7 @@ nm_platform_team_add (const char *name) * nm_platform_vlan_add: * @name: New interface name * @vlanid: VLAN identifier - * @vlanflags: VLAN flags from libnm-util + * @vlanflags: VLAN flags from libnm * * Create a software VLAN device. */ @@ -1266,7 +1330,7 @@ nm_platform_wifi_get_capabilities (int ifindex, NMDeviceWifiCapabilities *caps) } gboolean -nm_platform_wifi_get_bssid (int ifindex, struct ether_addr *bssid) +nm_platform_wifi_get_bssid (int ifindex, guint8 *bssid) { reset_error (); @@ -1377,14 +1441,38 @@ nm_platform_mesh_set_channel (int ifindex, guint32 channel) } gboolean -nm_platform_mesh_set_ssid (int ifindex, const GByteArray *ssid) +nm_platform_mesh_set_ssid (int ifindex, const guint8 *ssid, gsize len) { reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (ssid != NULL, FALSE); - return klass->mesh_set_ssid (platform, ifindex, ssid); + return klass->mesh_set_ssid (platform, ifindex, ssid, len); +} + +#define TO_STRING_DEV_BUF_SIZE (5+15+1) +static const char * +_to_string_dev (int ifindex, char *buf, size_t size) +{ + g_assert (buf && size >= TO_STRING_DEV_BUF_SIZE); + + if (ifindex) { + const char *name = ifindex > 0 ? nm_platform_link_get_name (ifindex) : NULL; + char *buf2; + + strcpy (buf, " dev "); + buf2 = buf + 5; + size -= 5; + + if (name) + g_strlcpy (buf2, name, size); + else + g_snprintf (buf2, size, "%d", ifindex); + } else + buf[0] = 0; + + return buf; } /******************************************************************/ @@ -1482,28 +1570,41 @@ nm_platform_ip6_address_add (int ifindex, } gboolean -nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen) +nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen, in_addr_t peer_address) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_peer[NM_UTILS_INET_ADDRSTRLEN]; + reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); g_return_val_if_fail (klass->ip4_address_delete, FALSE); - debug ("address: deleting IPv4 address %s/%d", nm_utils_inet4_ntop (address, NULL), plen); - return klass->ip4_address_delete (platform, ifindex, address, plen); + debug ("address: deleting IPv4 address %s/%d, %s%s%sifindex %d%s", + nm_utils_inet4_ntop (address, NULL), plen, + peer_address ? "peer " : "", + peer_address ? nm_utils_inet4_ntop (peer_address, str_peer) : "", + peer_address ? ", " : "", + ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); + return klass->ip4_address_delete (platform, ifindex, address, plen, peer_address); } gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, int plen) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); g_return_val_if_fail (klass->ip6_address_delete, FALSE); - debug ("address: deleting IPv6 address %s/%d", nm_utils_inet6_ntop (&address, NULL), plen); + debug ("address: deleting IPv6 address %s/%d, ifindex %d%s", + nm_utils_inet6_ntop (&address, NULL), plen, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip6_address_delete (platform, ifindex, address, plen); } @@ -1600,11 +1701,16 @@ _rebase_relative_time_on_now (guint32 timestamp, guint32 duration, guint32 now, static gboolean _address_get_lifetime (const NMPlatformIPAddress *address, guint32 now, guint32 padding, guint32 *out_lifetime, guint32 *out_preferred) { - gint32 lifetime, preferred; + guint32 lifetime, preferred; if (address->lifetime == 0) { *out_lifetime = NM_PLATFORM_LIFETIME_PERMANENT; *out_preferred = NM_PLATFORM_LIFETIME_PERMANENT; + + /* We treat lifetime==0 as permanent addresses to allow easy creation of such addresses + * (without requiring to set the lifetime fields to NM_PLATFORM_LIFETIME_PERMANENT). + * In that case we also expect that the other fields (timestamp and preferred) are left unset. */ + g_return_val_if_fail (address->timestamp == 0 && address->preferred == 0, TRUE); } else { lifetime = _rebase_relative_time_on_now (address->timestamp, address->lifetime, now, padding); if (!lifetime) @@ -1626,10 +1732,31 @@ _address_get_lifetime (const NMPlatformIPAddress *address, guint32 now, guint32 return TRUE; } +gboolean +nm_platform_ip4_check_reinstall_device_route (int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric) +{ + g_return_val_if_fail (address, FALSE); + + if ( ifindex <= 0 + || address->plen <= 0 + || address->plen >= 32) + return FALSE; + + if (device_route_metric == NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE) { + /* The automatically added route would be already our desired priority. + * Nothing to do. */ + return FALSE; + } + + return klass->ip4_check_reinstall_device_route (platform, ifindex, address, device_route_metric); +} + /** * nm_platform_ip4_address_sync: * @ifindex: Interface index * @known_addresses: List of addresses + * @device_route_metric: the route metric for adding subnet routes (replaces + * the kernel added routes). * * A convenience function to synchronize addresses for a specific interface * with the least possible disturbance. It simply removes addresses that are @@ -1638,7 +1765,7 @@ _address_get_lifetime (const NMPlatformIPAddress *address, guint32 now, guint32 * Returns: %TRUE on success. */ gboolean -nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) +nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses, guint32 device_route_metric) { GArray *addresses; NMPlatformIP4Address *address; @@ -1651,7 +1778,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) address = &g_array_index (addresses, NMPlatformIP4Address, i); if (!array_contains_ip4_address (known_addresses, address)) - nm_platform_ip4_address_delete (ifindex, address->address, address->plen); + nm_platform_ip4_address_delete (ifindex, address->address, address->plen, address->peer_address); } g_array_free (addresses, TRUE); @@ -1662,13 +1789,34 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) for (i = 0; i < known_addresses->len; i++) { const NMPlatformIP4Address *known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i); guint32 lifetime, preferred; + guint32 network; + gboolean reinstall_device_route = FALSE; /* add a padding of 5 seconds to avoid potential races. */ if (!_address_get_lifetime ((NMPlatformIPAddress *) known_address, now, 5, &lifetime, &preferred)) continue; + if (nm_platform_ip4_check_reinstall_device_route (ifindex, known_address, device_route_metric)) + reinstall_device_route = TRUE; + if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred, known_address->label)) return FALSE; + + if (reinstall_device_route) { + /* Kernel automatically adds a device route for us with metric 0. That is not what we want. + * Remove it, and re-add it. + * + * In face of having the same subnets on two different interfaces with the same metric, + * this is a problem. Surprisingly, kernel is able to add two routes for the same subnet/prefix,metric + * to different interfaces. We cannot. Adding one, would replace the other. This is avoided + * by the above nm_platform_ip4_check_reinstall_device_route() check. + */ + network = nm_utils_ip4_address_clear_host_address (known_address->address, known_address->plen); + (void) nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_KERNEL, network, known_address->plen, + 0, known_address->address, device_route_metric, 0); + (void) nm_platform_ip4_route_delete (ifindex, network, known_address->plen, + NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE); + } } return TRUE; @@ -1731,49 +1879,49 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) gboolean nm_platform_address_flush (int ifindex) { - return nm_platform_ip4_address_sync (ifindex, NULL) + return nm_platform_ip4_address_sync (ifindex, NULL, 0) && nm_platform_ip6_address_sync (ifindex, NULL); } /******************************************************************/ GArray * -nm_platform_ip4_route_get_all (int ifindex, gboolean include_default) +nm_platform_ip4_route_get_all (int ifindex, NMPlatformGetRouteMode mode) { reset_error (); - g_return_val_if_fail (ifindex > 0, NULL); + g_return_val_if_fail (ifindex >= 0, NULL); g_return_val_if_fail (klass->ip4_route_get_all, NULL); - return klass->ip4_route_get_all (platform, ifindex, include_default); + return klass->ip4_route_get_all (platform, ifindex, mode); } GArray * -nm_platform_ip6_route_get_all (int ifindex, gboolean include_default) +nm_platform_ip6_route_get_all (int ifindex, NMPlatformGetRouteMode mode) { reset_error (); - g_return_val_if_fail (ifindex > 0, NULL); + g_return_val_if_fail (ifindex >= 0, NULL); g_return_val_if_fail (klass->ip6_route_get_all, NULL); - return klass->ip6_route_get_all (platform, ifindex, include_default); + return klass->ip6_route_get_all (platform, ifindex, mode); } gboolean -nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, +nm_platform_ip4_route_add (int ifindex, NMIPConfigSource source, in_addr_t network, int plen, - in_addr_t gateway, int metric, int mss) + in_addr_t gateway, guint32 pref_src, + guint32 metric, guint32 mss) { reset_error (); g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (0 <= plen && plen <= 32, FALSE); - g_return_val_if_fail (metric >= 0, FALSE); - g_return_val_if_fail (mss >= 0, FALSE); g_return_val_if_fail (klass->ip4_route_add, FALSE); if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { NMPlatformIP4Route route = { 0 }; + char pref_src_buf[NM_UTILS_INET_ADDRSTRLEN]; route.ifindex = ifindex; route.source = source; @@ -1783,20 +1931,21 @@ nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, route.metric = metric; route.mss = mss; - debug ("route: adding or updating IPv4 route: %s", nm_platform_ip4_route_to_string (&route)); + debug ("route: adding or updating IPv4 route: %s%s%s%s", nm_platform_ip4_route_to_string (&route), + pref_src ? " (src: " : "", + pref_src ? nm_utils_inet4_ntop (pref_src, pref_src_buf) : "", + pref_src ? ")" : ""); } - return klass->ip4_route_add (platform, ifindex, source, network, plen, gateway, metric, mss); + return klass->ip4_route_add (platform, ifindex, source, network, plen, gateway, pref_src, metric, mss); } gboolean -nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, +nm_platform_ip6_route_add (int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, - int metric, int mss) + guint32 metric, guint32 mss) { g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (0 <= plen && plen <= 128, FALSE); - g_return_val_if_fail (metric >= 0, FALSE); - g_return_val_if_fail (mss >= 0, FALSE); g_return_val_if_fail (klass->ip6_route_add, FALSE); if (nm_logging_enabled (LOGL_DEBUG, LOGD_PLATFORM)) { @@ -1816,31 +1965,39 @@ nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, } gboolean -nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, int metric) +nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, guint32 metric) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (klass->ip4_route_delete, FALSE); - debug ("route: deleting IPv4 route %s/%d, metric=%d", nm_utils_inet4_ntop (network, NULL), plen, metric); + debug ("route: deleting IPv4 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", + nm_utils_inet4_ntop (network, NULL), plen, metric, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip4_route_delete (platform, ifindex, network, plen, metric); } gboolean -nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric) +nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, guint32 metric) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (klass->ip6_route_delete, FALSE); - debug ("route: deleting IPv6 route %s/%d, metric=%d", nm_utils_inet6_ntop (&network, NULL), plen, metric); + debug ("route: deleting IPv6 route %s/%d, metric=%"G_GUINT32_FORMAT", ifindex %d%s", + nm_utils_inet6_ntop (&network, NULL), plen, metric, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip6_route_delete (platform, ifindex, network, plen, metric); } gboolean -nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, int metric) +nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, guint32 metric) { reset_error (); @@ -1851,7 +2008,7 @@ nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, int metr } gboolean -nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, int metric) +nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, guint32 metric) { reset_error (); @@ -1907,6 +2064,8 @@ array_contains_ip6_route (const GArray *routes, const NMPlatformIP6Route *route) * A convenience function to synchronize routes for a specific interface * with the least possible disturbance. It simply removes routes that are * not listed and adds routes that are. + * Default routes are ignored (both in @known_routes and those already + * configured on the device). * * Returns: %TRUE on success. */ @@ -1920,12 +2079,12 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) int i, i_type; /* Delete unknown routes */ - routes = nm_platform_ip4_route_get_all (ifindex, FALSE); + routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT); for (i = 0; i < routes->len; i++) { route = &g_array_index (routes, NMPlatformIP4Route, i); if (!array_contains_ip4_route (known_routes, route)) - nm_platform_ip4_route_delete (ifindex, route->network, route->plen, route->metric); + (void) nm_platform_ip4_route_delete (ifindex, route->network, route->plen, route->metric); } if (!known_routes) { @@ -1938,6 +2097,9 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) for (i = 0; i < known_routes->len && success; i++) { known_route = &g_array_index (known_routes, NMPlatformIP4Route, i); + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route)) + continue; + if ((known_route->gateway == 0) ^ (i_type != 0)) { /* Make two runs over the list of routes. On the first, only add * device routes, on the second the others (gateway routes). */ @@ -1951,9 +2113,10 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) known_route->network, known_route->plen, known_route->gateway, + 0, known_route->metric, known_route->mss); - if (!success && known_route->source < NM_PLATFORM_SOURCE_USER) { + if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) { nm_log_dbg (LOGD_PLATFORM, "ignore error adding IPv4 route to kernel: %s", nm_platform_ip4_route_to_string (known_route)); success = TRUE; @@ -1974,6 +2137,8 @@ nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes) * A convenience function to synchronize routes for a specific interface * with the least possible disturbance. It simply removes routes that are * not listed and adds routes that are. + * Default routes are ignored (both in @known_routes and those already + * configured on the device). * * Returns: %TRUE on success. */ @@ -1987,7 +2152,7 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) int i, i_type; /* Delete unknown routes */ - routes = nm_platform_ip6_route_get_all (ifindex, FALSE); + routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT); for (i = 0; i < routes->len; i++) { route = &g_array_index (routes, NMPlatformIP6Route, i); route->ifindex = 0; @@ -2006,6 +2171,9 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) for (i = 0; i < known_routes->len && success; i++) { known_route = &g_array_index (known_routes, NMPlatformIP6Route, i); + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (known_route)) + continue; + if (IN6_IS_ADDR_UNSPECIFIED (&known_route->gateway) ^ (i_type != 0)) { /* Make two runs over the list of routes. On the first, only add * device routes, on the second the others (gateway routes). */ @@ -2021,7 +2189,7 @@ nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes) known_route->gateway, known_route->metric, known_route->mss); - if (!success && known_route->source < NM_PLATFORM_SOURCE_USER) { + if (!success && known_route->source < NM_IP_CONFIG_SOURCE_USER) { nm_log_dbg (LOGD_PLATFORM, "ignore error adding IPv6 route to kernel: %s", nm_platform_ip6_route_to_string (known_route)); success = TRUE; @@ -2044,26 +2212,26 @@ nm_platform_route_flush (int ifindex) /******************************************************************/ static const char * -source_to_string (NMPlatformSource source) +source_to_string (NMIPConfigSource source) { switch (source) { - case NM_PLATFORM_SOURCE_KERNEL: + case NM_IP_CONFIG_SOURCE_KERNEL: return "kernel"; - case NM_PLATFORM_SOURCE_SHARED: + case NM_IP_CONFIG_SOURCE_SHARED: return "shared"; - case NM_PLATFORM_SOURCE_IP4LL: + case NM_IP_CONFIG_SOURCE_IP4LL: return "ipv4ll"; - case NM_PLATFORM_SOURCE_PPP: + case NM_IP_CONFIG_SOURCE_PPP: return "ppp"; - case NM_PLATFORM_SOURCE_WWAN: + case NM_IP_CONFIG_SOURCE_WWAN: return "wwan"; - case NM_PLATFORM_SOURCE_VPN: + case NM_IP_CONFIG_SOURCE_VPN: return "vpn"; - case NM_PLATFORM_SOURCE_DHCP: + case NM_IP_CONFIG_SOURCE_DHCP: return "dhcp"; - case NM_PLATFORM_SOURCE_RDISC: + case NM_IP_CONFIG_SOURCE_RDISC: return "rdisc"; - case NM_PLATFORM_SOURCE_USER: + case NM_IP_CONFIG_SOURCE_USER: return "user"; default: break; @@ -2071,27 +2239,6 @@ source_to_string (NMPlatformSource source) return "unknown"; } -#define TO_STRING_DEV_BUF_SIZE (5+15+1) -static void -_to_string_dev (int ifindex, char *buf, size_t size) -{ - g_assert (buf && size >= TO_STRING_DEV_BUF_SIZE); - - if (ifindex){ - const char *name = ifindex > 0 ? nm_platform_link_get_name (ifindex) : NULL; - - strcpy (buf, " dev "); - buf += 5; - size -= 5; - - if (name) - g_strlcpy (buf, name, size); - else - g_snprintf (buf, size, "%d", ifindex); - } else - buf[0] = 0; -} - static const char * _lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) { @@ -2330,7 +2477,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route) _to_string_dev (route->ifindex, str_dev, sizeof (str_dev)); - g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d via %s%s metric %u mss %u src %s", + g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d via %s%s metric %"G_GUINT32_FORMAT" mss %"G_GUINT32_FORMAT" src %s", s_network, route->plen, s_gateway, str_dev, route->metric, route->mss, @@ -2363,7 +2510,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route) _to_string_dev (route->ifindex, str_dev, sizeof (str_dev)); - g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d via %s%s metric %u mss %u src %s", + g_snprintf (to_string_buffer, sizeof (to_string_buffer), "%s/%d via %s%s metric %"G_GUINT32_FORMAT" mss %"G_GUINT32_FORMAT" src %s", s_network, route->plen, s_gateway, str_dev, route->metric, route->mss, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 96b6cfab..848f78e4 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -18,17 +18,17 @@ * Copyright (C) 2009 - 2010 Red Hat, Inc. */ -#ifndef NM_PLATFORM_H -#define NM_PLATFORM_H +#ifndef __NETWORKMANAGER_PLATFORM_H__ +#define __NETWORKMANAGER_PLATFORM_H__ #include #include "nm-glib-compat.h" #include -#include #include #include -#include +#include +#include "nm-types.h" #define NM_TYPE_PLATFORM (nm_platform_get_type ()) #define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform)) @@ -72,54 +72,11 @@ typedef enum { NM_PLATFORM_REASON_CACHE_CHECK } NMPlatformReason; -typedef enum { - /* Please don't interpret type numbers outside nm-platform and use functions - * like nm_platform_link_is_software() and nm_platform_supports_slaves(). - * - * type & 0x10000 -> Software device type - * type & 0x20000 -> Type supports slaves - */ - - /* No type, used as error value */ - NM_LINK_TYPE_NONE, - - /* Unknown type */ - NM_LINK_TYPE_UNKNOWN, - - /* Hardware types */ - NM_LINK_TYPE_ETHERNET, - NM_LINK_TYPE_INFINIBAND, - NM_LINK_TYPE_OLPC_MESH, - NM_LINK_TYPE_WIFI, - NM_LINK_TYPE_WWAN_ETHERNET, /* WWAN pseudo-ethernet */ - NM_LINK_TYPE_WIMAX, - - /* Software types */ - NM_LINK_TYPE_DUMMY = 0x10000, - NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_IFB, - NM_LINK_TYPE_LOOPBACK, - NM_LINK_TYPE_MACVLAN, - NM_LINK_TYPE_MACVTAP, - NM_LINK_TYPE_OPENVSWITCH, - NM_LINK_TYPE_TAP, - NM_LINK_TYPE_TUN, - NM_LINK_TYPE_VETH, - NM_LINK_TYPE_VLAN, - NM_LINK_TYPE_VXLAN, - - /* Software types with slaves */ - NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000, - NM_LINK_TYPE_BOND, - NM_LINK_TYPE_TEAM, -} NMLinkType; - #define __NMPlatformObject_COMMON \ int ifindex; \ ; -typedef struct { +struct _NMPlatformLink { __NMPlatformObject_COMMON; char name[IFNAMSIZ]; NMLinkType type; @@ -132,7 +89,7 @@ typedef struct { gboolean connected; gboolean arp; guint mtu; -} NMPlatformLink; +}; typedef enum { NM_PLATFORM_SIGNAL_ADDED, @@ -143,19 +100,10 @@ typedef enum { #define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32 typedef enum { - /* In priority order; higher number == higher priority */ - NM_PLATFORM_SOURCE_UNKNOWN, - NM_PLATFORM_SOURCE_KERNEL, - NM_PLATFORM_SOURCE_SHARED, - NM_PLATFORM_SOURCE_IP4LL, - NM_PLATFORM_SOURCE_PPP, - NM_PLATFORM_SOURCE_WWAN, - NM_PLATFORM_SOURCE_VPN, - NM_PLATFORM_SOURCE_DHCP, - NM_PLATFORM_SOURCE_RDISC, - NM_PLATFORM_SOURCE_USER, -} NMPlatformSource; - + NM_PLATFORM_GET_ROUTE_MODE_ALL, + NM_PLATFORM_GET_ROUTE_MODE_NO_DEFAULT, + NM_PLATFORM_GET_ROUTE_MODE_ONLY_DEFAULT, +} NMPlatformGetRouteMode; typedef struct { __NMPlatformObject_COMMON; @@ -164,7 +112,7 @@ typedef struct { #define __NMPlatformIPAddress_COMMON \ __NMPlatformObject_COMMON; \ - NMPlatformSource source; \ + NMIPConfigSource source; \ \ /* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*(). * @@ -207,37 +155,55 @@ typedef struct { * NMPlatformIP4Address: * @timestamp: timestamp as returned by nm_utils_get_monotonic_timestamp_s() **/ -typedef struct { +struct _NMPlatformIP4Address { __NMPlatformIPAddress_COMMON; in_addr_t address; in_addr_t peer_address; /* PTP peer address */ char label[IFNAMSIZ]; -} NMPlatformIP4Address; +}; G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP4Address, address)); /** * NMPlatformIP6Address: * @timestamp: timestamp as returned by nm_utils_get_monotonic_timestamp_s() **/ -typedef struct { +struct _NMPlatformIP6Address { __NMPlatformIPAddress_COMMON; struct in6_addr address; struct in6_addr peer_address; guint flags; /* ifa_flags from , field type "unsigned int" is as used in rtnl_addr_get_flags. */ -} NMPlatformIP6Address; +}; G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Address, address)); +typedef union { + NMPlatformIPAddress ax; + NMPlatformIP4Address a4; + NMPlatformIP6Address a6; +} NMPlatformIPXAddress; + #undef __NMPlatformIPAddress_COMMON -#define NM_PLATFORM_ROUTE_METRIC_DEFAULT 1024 +/* Default value for adding an IPv4 route. This is also what iproute2 does. + * Note that contrary to IPv6, you can add routes with metric 0 and it is even + * the default. + */ +#define NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4 0 + +/* Default value for adding an IPv6 route. This is also what iproute2 does. + * Adding an IPv6 route with metric 0, kernel translates to IP6_RT_PRIO_USER (1024). */ +#define NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6 1024 + +/* For IPv4, kernel adds a device route (subnet routes) with metric 0 when user + * configures addresses. */ +#define NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE 0 #define __NMPlatformIPRoute_COMMON \ __NMPlatformObject_COMMON; \ - NMPlatformSource source; \ + NMIPConfigSource source; \ int plen; \ - guint metric; \ - guint mss; \ + guint32 metric; \ + guint32 mss; \ ; typedef struct { @@ -248,20 +214,29 @@ typedef struct { }; } NMPlatformIPRoute; -typedef struct { +#define NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route) \ + ( ((const NMPlatformIPRoute *) (route))->plen <= 0 ) + +struct _NMPlatformIP4Route { __NMPlatformIPRoute_COMMON; in_addr_t network; in_addr_t gateway; -} NMPlatformIP4Route; +}; G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OFFSET (NMPlatformIP4Route, network)); -typedef struct { +struct _NMPlatformIP6Route { __NMPlatformIPRoute_COMMON; struct in6_addr network; struct in6_addr gateway; -} NMPlatformIP6Route; +}; G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Route, network)); +typedef union { + NMPlatformIPRoute rx; + NMPlatformIP4Route r4; + NMPlatformIP6Route r6; +} NMPlatformIPXRoute; + #undef __NMPlatformIPRoute_COMMON @@ -384,6 +359,9 @@ typedef struct { gboolean (*link_is_connected) (NMPlatform *, int ifindex); gboolean (*link_uses_arp) (NMPlatform *, int ifindex); + gboolean (*link_get_user_ipv6ll_enabled) (NMPlatform *, int ifindex); + gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + gconstpointer (*link_get_address) (NMPlatform *, int ifindex, size_t *length); gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); guint32 (*link_get_mtu) (NMPlatform *, int ifindex); @@ -417,7 +395,7 @@ typedef struct { gboolean (*gre_get_properties) (NMPlatform *, int ifindex, NMPlatformGreProperties *props); gboolean (*wifi_get_capabilities) (NMPlatform *, int ifindex, NMDeviceWifiCapabilities *caps); - gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, struct ether_addr *bssid); + gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, guint8 *bssid); GByteArray *(*wifi_get_ssid) (NMPlatform *, int ifindex); guint32 (*wifi_get_frequency) (NMPlatform *, int ifindex); int (*wifi_get_quality) (NMPlatform *, int ifindex); @@ -429,7 +407,7 @@ typedef struct { guint32 (*mesh_get_channel) (NMPlatform *, int ifindex); gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel); - gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const GByteArray *ssid); + gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len); GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex); GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex); @@ -440,25 +418,28 @@ typedef struct { gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, struct in6_addr peer_address, int plen, guint32 lifetime, guint32 preferred_lft, guint flags); - gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen); + gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen); gboolean (*ip4_address_exists) (NMPlatform *, int ifindex, in_addr_t address, int plen); gboolean (*ip6_address_exists) (NMPlatform *, int ifindex, struct in6_addr address, int plen); - GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, gboolean include_default); - GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, gboolean include_default); - gboolean (*ip4_route_add) (NMPlatform *, int ifindex, NMPlatformSource source, + gboolean (*ip4_check_reinstall_device_route) (NMPlatform *, int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric); + + GArray * (*ip4_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteMode mode); + GArray * (*ip6_route_get_all) (NMPlatform *, int ifindex, NMPlatformGetRouteMode mode); + gboolean (*ip4_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source, in_addr_t network, int plen, in_addr_t gateway, - int prio, int mss); - gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMPlatformSource source, + guint32 pref_src, guint32 metric, guint32 mss); + gboolean (*ip6_route_add) (NMPlatform *, int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, - int prio, int mss); - gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, int plen, int metric); - gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, int metric); - gboolean (*ip4_route_exists) (NMPlatform *, int ifindex, in_addr_t network, int plen, int metric); - gboolean (*ip6_route_exists) (NMPlatform *, int ifindex, struct in6_addr network, int plen, int metric); + guint32 metric, guint32 mss); + gboolean (*ip4_route_delete) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric); + gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric); + gboolean (*ip4_route_exists) (NMPlatform *, int ifindex, in_addr_t network, int plen, guint32 metric); + gboolean (*ip6_route_exists) (NMPlatform *, int ifindex, struct in6_addr network, int plen, guint32 metric); gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *); + gboolean (*check_support_user_ipv6ll) (NMPlatform *); } NMPlatformClass; /* NMPlatform signals @@ -524,6 +505,9 @@ gboolean nm_platform_link_is_up (int ifindex); gboolean nm_platform_link_is_connected (int ifindex); gboolean nm_platform_link_uses_arp (int ifindex); +gboolean nm_platform_link_get_user_ipv6ll_enabled (int ifindex); +gboolean nm_platform_link_set_user_ipv6ll_enabled (int ifindex, gboolean enabled); + gconstpointer nm_platform_link_get_address (int ifindex, size_t *length); gboolean nm_platform_link_set_address (int ifindex, const void *address, size_t length); guint32 nm_platform_link_get_mtu (int ifindex); @@ -557,7 +541,7 @@ gboolean nm_platform_vxlan_get_properties (int ifindex, NMPlatformVxlanPropertie gboolean nm_platform_gre_get_properties (int ifindex, NMPlatformGreProperties *props); gboolean nm_platform_wifi_get_capabilities (int ifindex, NMDeviceWifiCapabilities *caps); -gboolean nm_platform_wifi_get_bssid (int ifindex, struct ether_addr *bssid); +gboolean nm_platform_wifi_get_bssid (int ifindex, guint8 *bssid); GByteArray *nm_platform_wifi_get_ssid (int ifindex); guint32 nm_platform_wifi_get_frequency (int ifindex); int nm_platform_wifi_get_quality (int ifindex); @@ -569,7 +553,7 @@ void nm_platform_wifi_indicate_addressing_running (int ifindex, gboolean guint32 nm_platform_mesh_get_channel (int ifindex); gboolean nm_platform_mesh_set_channel (int ifindex, guint32 channel); -gboolean nm_platform_mesh_set_ssid (int ifindex, const GByteArray *ssid); +gboolean nm_platform_mesh_set_ssid (int ifindex, const guint8 *ssid, gsize len); GArray *nm_platform_ip4_address_get_all (int ifindex); GArray *nm_platform_ip6_address_get_all (int ifindex); @@ -580,27 +564,28 @@ gboolean nm_platform_ip4_address_add (int ifindex, gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, struct in6_addr peer_address, int plen, guint32 lifetime, guint32 preferred_lft, guint flags); -gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen); +gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, int plen); gboolean nm_platform_ip4_address_exists (int ifindex, in_addr_t address, int plen); gboolean nm_platform_ip6_address_exists (int ifindex, struct in6_addr address, int plen); -gboolean nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses); +gboolean nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses, guint32 device_route_metric); gboolean nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses); gboolean nm_platform_address_flush (int ifindex); -GArray *nm_platform_ip4_route_get_all (int ifindex, gboolean include_default); -GArray *nm_platform_ip6_route_get_all (int ifindex, gboolean include_default); -gboolean nm_platform_route_set_metric (int ifindex, int metric); -gboolean nm_platform_ip4_route_add (int ifindex, NMPlatformSource source, +gboolean nm_platform_ip4_check_reinstall_device_route (int ifindex, const NMPlatformIP4Address *address, guint32 device_route_metric); + +GArray *nm_platform_ip4_route_get_all (int ifindex, NMPlatformGetRouteMode mode); +GArray *nm_platform_ip6_route_get_all (int ifindex, NMPlatformGetRouteMode mode); +gboolean nm_platform_ip4_route_add (int ifindex, NMIPConfigSource source, in_addr_t network, int plen, in_addr_t gateway, - int metric, int mss); -gboolean nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, + guint32 pref_src, guint32 metric, guint32 mss); +gboolean nm_platform_ip6_route_add (int ifindex, NMIPConfigSource source, struct in6_addr network, int plen, struct in6_addr gateway, - int metric, int mss); -gboolean nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, int metric); -gboolean nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric); -gboolean nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, int metric); -gboolean nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, int metric); + guint32 metric, guint32 mss); +gboolean nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, guint32 metric); +gboolean nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, guint32 metric); +gboolean nm_platform_ip4_route_exists (int ifindex, in_addr_t network, int plen, guint32 metric); +gboolean nm_platform_ip6_route_exists (int ifindex, struct in6_addr network, int plen, guint32 metric); gboolean nm_platform_ip4_route_sync (int ifindex, const GArray *known_routes); gboolean nm_platform_ip6_route_sync (int ifindex, const GArray *known_routes); gboolean nm_platform_route_flush (int ifindex); @@ -619,16 +604,10 @@ int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6R gboolean nm_platform_check_support_libnl_extended_ifa_flags (void); gboolean nm_platform_check_support_kernel_extended_ifa_flags (void); +gboolean nm_platform_check_support_user_ipv6ll (void); void nm_platform_addr_flags2str (int flags, char *buf, size_t size); int nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPlatformIPAddress *b); -#define auto_g_free __attribute__((cleanup(put_g_free))) -static void __attribute__((unused)) -put_g_free (void *ptr) -{ - g_clear_pointer ((gpointer *) ptr, g_free); -} - -#endif /* NM_PLATFORM_H */ +#endif /* __NETWORKMANAGER_PLATFORM_H__ */ diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index 9b10ea7b..b06e25e0 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -1,14 +1,13 @@ AM_CPPFLAGS = \ -I${top_srcdir} \ -I${top_srcdir}/include \ - -I${top_builddir}/include \ -I${top_srcdir}/src \ -I${top_builddir}/src \ - -I${top_srcdir}/src/logging \ - -I${top_srcdir}/libnm-util \ - -I${top_builddir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I${srcdir}/.. \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(GUDEV_CFLAGS) \ @@ -111,6 +110,6 @@ test_cleanup_linux_CPPFLAGS = \ test_cleanup_linux_LDADD = $(PLATFORM_LDADD) #@VALGRIND_RULES@ -TESTS = test-link-fake test-address-fake test-route-fake test-cleanup-fake test-link-linux test-address-linux test-route-linux test-cleanup-linux +TESTS = test-link-fake test-address-fake test-route-fake test-cleanup-fake test-address-linux test-route-linux test-cleanup-linux diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in index 6b03e315..052636ab 100644 --- a/src/platform/tests/Makefile.in +++ b/src/platform/tests/Makefile.in @@ -86,8 +86,8 @@ noinst_PROGRAMS = dump$(EXEEXT) monitor$(EXEEXT) platform$(EXEEXT) \ test-cleanup-fake$(EXEEXT) test-cleanup-linux$(EXEEXT) TESTS = test-link-fake$(EXEEXT) test-address-fake$(EXEEXT) \ test-route-fake$(EXEEXT) test-cleanup-fake$(EXEEXT) \ - test-link-linux$(EXEEXT) test-address-linux$(EXEEXT) \ - test-route-linux$(EXEEXT) test-cleanup-linux$(EXEEXT) + test-address-linux$(EXEEXT) test-route-linux$(EXEEXT) \ + test-cleanup-linux$(EXEEXT) subdir = src/platform/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -299,6 +299,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -422,6 +424,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -441,6 +444,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -467,7 +471,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -547,10 +551,10 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/include \ - -I${top_builddir}/include -I${top_srcdir}/src \ - -I${top_builddir}/src -I${top_srcdir}/src/logging \ - -I${top_srcdir}/libnm-util -I${top_builddir}/libnm-util \ + -I${top_srcdir}/src -I${top_builddir}/src \ + -I${top_srcdir}/libnm-core -I${top_builddir}/libnm-core \ -I${srcdir}/.. -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(GLIB_CFLAGS) \ $(GUDEV_CFLAGS) $(LIBNL_CFLAGS) $(am__append_1) PLATFORM_SOURCES = \ diff --git a/src/platform/tests/dump.c b/src/platform/tests/dump.c index e97ef138..3bb61da4 100644 --- a/src/platform/tests/dump.c +++ b/src/platform/tests/dump.c @@ -1,3 +1,5 @@ +#include "config.h" + #include #include #include @@ -83,8 +85,8 @@ dump_interface (NMPlatformLink *link) g_array_unref (ip4_addresses); g_array_unref (ip6_addresses); - ip4_routes = nm_platform_ip4_route_get_all (link->ifindex, TRUE); - ip6_routes = nm_platform_ip6_route_get_all (link->ifindex, TRUE); + ip4_routes = nm_platform_ip4_route_get_all (link->ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); + ip6_routes = nm_platform_ip6_route_get_all (link->ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); g_assert (ip4_routes); g_assert (ip6_routes); diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index d56cc2bf..9aff1047 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -1,3 +1,5 @@ +#include "config.h" + #include #include diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c index ea8bd0e3..eea6610d 100644 --- a/src/platform/tests/platform.c +++ b/src/platform/tests/platform.c @@ -18,12 +18,15 @@ * Copyright (C) 2013 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include #include +#include "gsystem-local-alloc.h" #include "nm-platform.h" #include "nm-linux-platform.h" #include "nm-fake-platform.h" @@ -47,7 +50,7 @@ do_sysctl_set (char **argv) static gboolean do_sysctl_get (char **argv) { - auto_g_free char *value = nm_platform_sysctl_get (argv[0]); + gs_free char *value = nm_platform_sysctl_get (argv[0]); printf ("%s\n", value); @@ -281,7 +284,7 @@ do_master_get_option (char **argv) { int ifindex = parse_ifindex (*argv++); const char *option = *argv++; - auto_g_free char *value = nm_platform_master_get_option (ifindex, option); + gs_free char *value = nm_platform_master_get_option (ifindex, option); printf ("%s\n", value); @@ -303,7 +306,7 @@ do_slave_get_option (char **argv) { int ifindex = parse_ifindex (*argv++); const char *option = *argv++; - auto_g_free char *value = nm_platform_slave_get_option (ifindex, option); + gs_free char *value = nm_platform_slave_get_option (ifindex, option); printf ("%s\n", value); @@ -532,6 +535,9 @@ parse_ip_address (int family, char *str, gpointer address, int *plen) { char *endptr; + if (plen) + *plen = 0; + if (plen) { char *ptr = strchr (str, '/'); if (ptr) { @@ -594,7 +600,7 @@ do_ip6_address_add (char **argv) return FALSE; } -#define ADDR_CMD_FULL(v, cmdname, print) \ +#define ADDR_CMD_FULL(v, cmdname, print, ...) \ static gboolean \ do_##v##_address_##cmdname (char **argv) \ { \ @@ -602,7 +608,7 @@ do_ip6_address_add (char **argv) v##_t address; \ int plen; \ if (ifindex && parse_##v##_address (*argv++, &address, &plen)) { \ - gboolean value = nm_platform_##v##_address_##cmdname (ifindex, address, plen); \ + gboolean value = nm_platform_##v##_address_##cmdname (ifindex, address, plen, ##__VA_ARGS__); \ if (print) { \ print_boolean (value); \ return TRUE; \ @@ -611,7 +617,7 @@ do_ip6_address_add (char **argv) } else \ return FALSE; \ } -#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE) ADDR_CMD_FULL (ip6, cmdname, FALSE) +#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0) ADDR_CMD_FULL (ip6, cmdname, FALSE) #define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE) ADDR_CMD (delete) @@ -627,7 +633,7 @@ do_ip4_route_get_all (char **argv) int i; if (ifindex) { - routes = nm_platform_ip4_route_get_all (ifindex, TRUE); + routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); for (i = 0; i < routes->len; i++) { route = &g_array_index (routes, NMPlatformIP4Route, i); inet_ntop (AF_INET, &route->network, networkstr, sizeof (networkstr)); @@ -651,7 +657,7 @@ do_ip6_route_get_all (char **argv) int i; if (ifindex) { - routes = nm_platform_ip6_route_get_all (ifindex, TRUE); + routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); for (i = 0; i < routes->len; i++) { route = &g_array_index (routes, NMPlatformIP6Route, i); inet_ntop (AF_INET6, &route->network, networkstr, sizeof (networkstr)); @@ -677,8 +683,8 @@ do_ip4_route_add (char **argv) metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); - return nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, - network, plen, gateway, + return nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, + network, plen, gateway, 0, metric, mss); } @@ -693,7 +699,7 @@ do_ip6_route_add (char **argv) parse_ip6_address (*argv++, &gateway, NULL); metric = strtol (*argv++, NULL, 10); mss = strtol (*argv++, NULL, 10); - return nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, + return nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss); } diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 3fef5375..3ef13b8e 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -1,3 +1,5 @@ +#include "config.h" + #include "test-common.h" #define DEVICE_NAME "nm-test-device" @@ -91,13 +93,13 @@ test_ip4_address (void) g_array_unref (addresses); /* Remove address */ - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_removed); /* Remove address again */ - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); free_signal (address_added); @@ -196,7 +198,7 @@ test_ip4_address_external (void) g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_added); /*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_removed);*/ diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index e60d82f0..afbb438c 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -1,9 +1,11 @@ +#include "config.h" + #include "test-common.h" #define DEVICE_NAME "nm-test-device" static void -test_cleanup_internal () +test_cleanup_internal (void) { SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); int ifindex; @@ -43,17 +45,17 @@ test_cleanup_internal () /* Add routes and addresses */ g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred, NULL)); g_assert (nm_platform_ip6_address_add (ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags)); - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway4, 32, INADDR_ANY, metric, mss)); - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network4, plen4, gateway4, metric, mss)); - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway4, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway6, 128, in6addr_any, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network6, plen6, gateway6, metric, mss)); - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway6, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, gateway6, 128, in6addr_any, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network6, plen6, gateway6, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway6, metric, mss)); addresses4 = nm_platform_ip4_address_get_all (ifindex); addresses6 = nm_platform_ip6_address_get_all (ifindex); - routes4 = nm_platform_ip4_route_get_all (ifindex, TRUE); - routes6 = nm_platform_ip6_route_get_all (ifindex, TRUE); + routes4 = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); + routes6 = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); g_assert_cmpint (addresses4->len, ==, 1); g_assert_cmpint (addresses6->len, ==, 1); @@ -70,8 +72,8 @@ test_cleanup_internal () addresses4 = nm_platform_ip4_address_get_all (ifindex); addresses6 = nm_platform_ip6_address_get_all (ifindex); - routes4 = nm_platform_ip4_route_get_all (ifindex, TRUE); - routes6 = nm_platform_ip6_route_get_all (ifindex, TRUE); + routes4 = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); + routes6 = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); g_assert_cmpint (addresses4->len, ==, 0); g_assert_cmpint (addresses6->len, ==, 0); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 59a770c6..ab40f652 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1,3 +1,5 @@ +#include "config.h" + #include "test-common.h" #include "nm-test-utils.h" diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index a3f757c2..8bd2ef44 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1,3 +1,5 @@ +#include "config.h" + #include "test-common.h" #include "nm-test-utils.h" @@ -130,6 +132,7 @@ software_add (NMLinkType link_type, const char *name) default: g_error ("Link type %d unhandled.", link_type); } + g_assert_not_reached (); } static void @@ -188,12 +191,12 @@ test_slave (int master, int type, SignalData *master_changed) /* Older team versions (e.g. Fedora 17) have a bug that team master stays * IFF_LOWER_UP even if its slave is down. Double check it with iproute2 and if * `ip link` also claims master to be up, accept it. */ - char *stdout = NULL; + char *stdout_str = NULL; - nmtst_spawn_sync (NULL, &stdout, NULL, 0, "/sbin/ip", "link", "show", "dev", nm_platform_link_get_name (master)); + nmtst_spawn_sync (NULL, &stdout_str, NULL, 0, "/sbin/ip", "link", "show", "dev", nm_platform_link_get_name (master)); - g_assert (strstr (stdout, "LOWER_UP")); - g_free (stdout); + g_assert (strstr (stdout_str, "LOWER_UP")); + g_free (stdout_str); } else g_assert_not_reached (); } @@ -379,7 +382,7 @@ test_team (void) } static void -test_vlan () +test_vlan (void) { test_software (NM_LINK_TYPE_VLAN, "vlan"); } diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index d45730ac..2c70b412 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -1,3 +1,5 @@ +#include "config.h" + #include "test-common.h" #include "nm-test-utils.h" @@ -48,7 +50,7 @@ ip6_route_callback (NMPlatform *platform, int ifindex, NMPlatformIP6Route *recei } static void -test_ip4_route () +test_ip4_route (void) { int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_route_callback); @@ -59,63 +61,64 @@ test_ip4_route () in_addr_t network; int plen = 24; in_addr_t gateway; - int metric = 20; + /* Choose a high metric so that we hopefully don't conflict. */ + int metric = 22986; int mss = 1000; inet_pton (AF_INET, "192.0.3.0", &network); inet_pton (AF_INET, "198.51.100.1", &gateway); /* Add route to gateway */ - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway, 32, INADDR_ANY, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 32, INADDR_ANY, 0, metric, mss)); no_error (); accept_signal (route_added); /* Add route */ g_assert (!nm_platform_ip4_route_exists (ifindex, network, plen, metric)); no_error (); - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); no_error (); g_assert (nm_platform_ip4_route_exists (ifindex, network, plen, metric)); no_error (); accept_signal (route_added); /* Add route again */ - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss)); no_error (); accept_signal (route_changed); /* Add default route */ g_assert (!nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); no_error (); - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); no_error (); g_assert (nm_platform_ip4_route_exists (ifindex, 0, 0, metric)); no_error (); accept_signal (route_added); /* Add default route again */ - g_assert (nm_platform_ip4_route_add (ifindex, NM_PLATFORM_SOURCE_USER, 0, 0, gateway, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss)); no_error (); accept_signal (route_changed); /* Test route listing */ - routes = nm_platform_ip4_route_get_all (ifindex, TRUE); + routes = nm_platform_ip4_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_PLATFORM_SOURCE_USER; + rts[0].source = NM_IP_CONFIG_SOURCE_USER; rts[0].network = gateway; rts[0].plen = 32; rts[0].ifindex = ifindex; rts[0].gateway = INADDR_ANY; rts[0].metric = metric; rts[0].mss = mss; - rts[1].source = NM_PLATFORM_SOURCE_USER; + rts[1].source = NM_IP_CONFIG_SOURCE_USER; rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; rts[1].metric = metric; rts[1].mss = mss; - rts[2].source = NM_PLATFORM_SOURCE_USER; + rts[2].source = NM_IP_CONFIG_SOURCE_USER; rts[2].network = 0; rts[2].plen = 0; rts[2].ifindex = ifindex; @@ -143,7 +146,7 @@ test_ip4_route () } static void -test_ip6_route () +test_ip6_route (void) { int ifindex = nm_platform_link_get_ifindex (DEVICE_NAME); SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_route_callback); @@ -154,63 +157,64 @@ test_ip6_route () struct in6_addr network; int plen = 64; struct in6_addr gateway; - int metric = 20; + /* Choose a high metric so that we hopefully don't conflict. */ + int metric = 22987; int mss = 1000; inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network); inet_pton (AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway); /* Add route to gateway */ - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, gateway, 128, in6addr_any, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, metric, mss)); no_error (); accept_signal (route_added); /* Add route */ g_assert (!nm_platform_ip6_route_exists (ifindex, network, plen, metric)); no_error (); - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss)); no_error (); g_assert (nm_platform_ip6_route_exists (ifindex, network, plen, metric)); no_error (); accept_signal (route_added); /* Add route again */ - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, network, plen, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss)); no_error (); accept_signal (route_changed); /* Add default route */ g_assert (!nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); no_error (); - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); no_error (); g_assert (nm_platform_ip6_route_exists (ifindex, in6addr_any, 0, metric)); no_error (); accept_signal (route_added); /* Add default route again */ - g_assert (nm_platform_ip6_route_add (ifindex, NM_PLATFORM_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); + g_assert (nm_platform_ip6_route_add (ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss)); no_error (); accept_signal (route_changed); /* Test route listing */ - routes = nm_platform_ip6_route_get_all (ifindex, TRUE); + routes = nm_platform_ip6_route_get_all (ifindex, NM_PLATFORM_GET_ROUTE_MODE_ALL); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_PLATFORM_SOURCE_USER; + rts[0].source = 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 = metric; rts[0].mss = mss; - rts[1].source = NM_PLATFORM_SOURCE_USER; + rts[1].source = NM_IP_CONFIG_SOURCE_USER; rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; rts[1].metric = metric; rts[1].mss = mss; - rts[2].source = NM_PLATFORM_SOURCE_USER; + rts[2].source = 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-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 25ebd1b3..752da926 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -20,7 +20,8 @@ * Copyright (C) 2011 Intel Corporation. All rights reserved. */ -#include +#include "config.h" + #include #include #include @@ -442,7 +443,7 @@ wifi_nl80211_get_ssid (WifiData *data) } static gboolean -wifi_nl80211_get_bssid (WifiData *data, struct ether_addr *out_bssid) +wifi_nl80211_get_bssid (WifiData *data, guint8 *out_bssid) { WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; @@ -679,11 +680,20 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, +#ifdef NL80211_FREQUENCY_ATTR_NO_IR + [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG }, +#else [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, +#endif [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 }, }; +#ifdef NL80211_FREQUENCY_ATTR_NO_IR + G_STATIC_ASSERT (NL80211_FREQUENCY_ATTR_PASSIVE_SCAN == NL80211_FREQUENCY_ATTR_NO_IR && NL80211_FREQUENCY_ATTR_NO_IBSS == NL80211_FREQUENCY_ATTR_NO_IR); +#else + G_STATIC_ASSERT (NL80211_FREQUENCY_ATTR_PASSIVE_SCAN != NL80211_FREQUENCY_ATTR_NO_IBSS); +#endif if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen (gnlh, 0), NULL) < 0) @@ -924,48 +934,3 @@ error: return NULL; } -gboolean -wifi_nl80211_is_wifi (const char *iface) -{ - struct nl_sock *nl_sock; - struct nl_cb *nl_cb = NULL; - struct nl_msg *msg = NULL; - int id, ifindex; - struct nl80211_iface_info iface_info = { - .mode = NM_802_11_MODE_UNKNOWN, - }; - gboolean is_wifi = FALSE; - - nl_sock = nl_socket_alloc (); - if (nl_sock == NULL) - return FALSE; - - if (genl_connect (nl_sock)) - goto error; - - ifindex = nm_platform_link_get_ifindex (iface); - if (ifindex < 0) - goto error; - - id = genl_ctrl_resolve (nl_sock, "nl80211"); - if (id < 0) - goto error; - - nl_cb = nl_cb_alloc (NL_CB_DEFAULT); - if (nl_cb) { - msg = _nl80211_alloc_msg (id, ifindex, -1, NL80211_CMD_GET_INTERFACE, 0); - if (_nl80211_send_and_recv (nl_sock, - nl_cb, - msg, - nl80211_iface_info_handler, - &iface_info) >= 0) - is_wifi = (iface_info.mode != NM_802_11_MODE_UNKNOWN); - } - - error: - if (nl_cb) - nl_cb_put (nl_cb); - nl_socket_free (nl_sock); - return is_wifi; -} - diff --git a/src/platform/wifi/wifi-utils-nl80211.h b/src/platform/wifi/wifi-utils-nl80211.h index 2a7fe874..b3e8c897 100644 --- a/src/platform/wifi/wifi-utils-nl80211.h +++ b/src/platform/wifi/wifi-utils-nl80211.h @@ -18,13 +18,11 @@ * Copyright (C) 2011 Intel Corporation. All rights reserved. */ -#ifndef WIFI_UTILS_NL80211_H -#define WIFI_UTILS_NL80211_H +#ifndef __WIFI_UTILS_NL80211_H__ +#define __WIFI_UTILS_NL80211_H__ #include "wifi-utils.h" WifiData *wifi_nl80211_init (const char *iface, int ifindex); -gboolean wifi_nl80211_is_wifi (const char *iface); - -#endif /* WIFI_UTILS_NL80211_H */ +#endif /* __WIFI_UTILS_NL80211_H__ */ diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index e7601752..aaedd5b7 100644 --- a/src/platform/wifi/wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -18,12 +18,12 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#ifndef WIFI_UTILS_PRIVATE_H -#define WIFI_UTILS_PRIVATE_H +#ifndef __WIFI_UTILS_PRIVATE_H__ +#define __WIFI_UTILS_PRIVATE_H__ #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "wifi-utils.h" struct WifiData { @@ -47,7 +47,7 @@ struct WifiData { /* Return current bitrate in Kbps */ guint32 (*get_rate) (WifiData *data); - gboolean (*get_bssid) (WifiData *data, struct ether_addr *out_bssid); + gboolean (*get_bssid) (WifiData *data, guint8 *out_bssid); /* Return a signal strength percentage 0 - 100% for the current BSSID; * return -1 on errors or if not associated. @@ -66,7 +66,7 @@ struct WifiData { gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); /* ssid == NULL means "auto SSID" */ - gboolean (*set_mesh_ssid) (WifiData *data, const GByteArray *ssid); + gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len); gboolean (*indicate_addressing_running) (WifiData *data, gboolean running); }; @@ -74,4 +74,4 @@ struct WifiData { gpointer wifi_data_new (const char *iface, int ifindex, gsize len); void wifi_data_free (WifiData *data); -#endif /* WIFI_UTILS_PRIVATE_H */ +#endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index cc94b69a..e0331de7 100644 --- a/src/platform/wifi/wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -19,7 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -41,7 +42,6 @@ #include #include #include -#include #include @@ -230,7 +230,7 @@ wifi_wext_get_ssid (WifiData *data) } static gboolean -wifi_wext_get_bssid (WifiData *data, struct ether_addr *out_bssid) +wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid) { WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; @@ -243,7 +243,7 @@ wifi_wext_get_bssid (WifiData *data, struct ether_addr *out_bssid) wext->parent.iface, strerror (errno)); return FALSE; } - memcpy (out_bssid->ether_addr_octet, &(wrq.u.ap_addr.sa_data), ETH_ALEN); + memcpy (out_bssid, &(wrq.u.ap_addr.sa_data), ETH_ALEN); return TRUE; } @@ -421,18 +421,15 @@ wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) } static gboolean -wifi_wext_set_mesh_ssid (WifiData *data, const GByteArray *ssid) +wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; - guint32 len = 0; char buf[IW_ESSID_MAX_SIZE + 1]; memset (buf, 0, sizeof (buf)); - if (ssid) { - len = ssid->len; - memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len)); - } + memcpy (buf, ssid, MIN (sizeof (buf) - 1, len)); + wrq.u.essid.pointer = (caddr_t) buf; wrq.u.essid.length = len; wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */ @@ -445,7 +442,7 @@ wifi_wext_set_mesh_ssid (WifiData *data, const GByteArray *ssid) nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC, "(%s): error setting SSID to '%s': %s", wext->parent.iface, - ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(null)", + ssid ? nm_utils_escape_ssid (ssid, len) : "(null)", strerror (errno)); } diff --git a/src/platform/wifi/wifi-utils-wext.h b/src/platform/wifi/wifi-utils-wext.h index 96ad74eb..e168fe28 100644 --- a/src/platform/wifi/wifi-utils-wext.h +++ b/src/platform/wifi/wifi-utils-wext.h @@ -18,8 +18,8 @@ * Copyright (C) 2011 Red Hat, Inc. */ -#ifndef WIFI_UTILS_WEXT_H -#define WIFI_UTILS_WEXT_H +#ifndef __WIFI_UTILS_WEXT_H__ +#define __WIFI_UTILS_WEXT_H__ #include "wifi-utils.h" @@ -27,4 +27,4 @@ WifiData *wifi_wext_init (const char *iface, int ifindex, gboolean check_scan); gboolean wifi_wext_is_wifi (const char *iface); -#endif /* WIFI_UTILS_WEXT_H */ +#endif /* __WIFI_UTILS_WEXT_H__ */ diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index ff480275..daef881b 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -19,7 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -120,12 +121,12 @@ wifi_utils_get_ssid (WifiData *data) } gboolean -wifi_utils_get_bssid (WifiData *data, struct ether_addr *out_bssid) +wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid) { g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (out_bssid != NULL, FALSE); - memset (out_bssid, 0, sizeof (*out_bssid)); + memset (out_bssid, 0, ETH_ALEN); return data->get_bssid (data, out_bssid); } @@ -161,13 +162,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, const char *sysfs_path, const char *devtype) { char phy80211_path[255]; struct stat s; g_return_val_if_fail (iface != NULL, FALSE); + if (g_strcmp0 (devtype, "wlan") == 0) { + /* All Wi-Fi drivers should set DEVTYPE=wlan. Since the kernel's + * cfg80211/nl80211 stack does, this check should match any nl80211 + * capable driver (including mac82011-based ones). */ + return TRUE; + } + if (sysfs_path) { /* Check for nl80211 sysfs paths */ g_snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path); @@ -175,9 +183,6 @@ wifi_utils_is_wifi (const char *iface, const char *sysfs_path) return TRUE; } - if (wifi_nl80211_is_wifi (iface)) - return TRUE; - #if HAVE_WEXT if (wifi_wext_is_wifi (iface)) return TRUE; @@ -207,11 +212,11 @@ wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) } gboolean -wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid) +wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (data->set_mesh_ssid != NULL, FALSE); - return data->set_mesh_ssid (data, ssid); + return data->set_mesh_ssid (data, ssid, len); } gboolean diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index 455e075f..f1b57ace 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -19,17 +19,17 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef WIFI_UTILS_H -#define WIFI_UTILS_H +#ifndef __WIFI_UTILS_H__ +#define __WIFI_UTILS_H__ #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" typedef struct WifiData WifiData; -gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path); +gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path, const char *devtype); WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); @@ -50,8 +50,8 @@ guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); /* Caller must free returned byte array */ GByteArray *wifi_utils_get_ssid (WifiData *data); -/* Caller must free returned byte array */ -gboolean wifi_utils_get_bssid (WifiData *data, struct ether_addr *out_bssid); +/* out_bssid must be ETH_ALEN bytes */ +gboolean wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid); /* Returns current bitrate in Kbps */ guint32 wifi_utils_get_rate (WifiData *data); @@ -71,6 +71,6 @@ guint32 wifi_utils_get_mesh_channel (WifiData *data); gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); -gboolean wifi_utils_set_mesh_ssid (WifiData *data, const GByteArray *ssid); +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len); -#endif /* WIFI_UTILS_H */ +#endif /* __WIFI_UTILS_H__ */ diff --git a/src/posix-signals/nm-posix-signals.c b/src/posix-signals/nm-posix-signals.c deleted file mode 100644 index 22fed831..00000000 --- a/src/posix-signals/nm-posix-signals.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2012 Red Hat, Inc. - */ - -#include "config.h" - -#include - -#include "nm-posix-signals.h" - - -/* Stores the original signal mask of NetworkManager process */ -static sigset_t nm_original_signal_mask; - -void -nm_save_original_signal_mask (sigset_t sig_mask) -{ - nm_original_signal_mask = sig_mask; -} - -const sigset_t * -nm_get_original_signal_mask (void) -{ - return &nm_original_signal_mask; -} - -/* - * Unblock signals. - * If a signal set is passed, those signals are unblocked. If user_data is NULL - * the process' signal mask is set to the saved original mask. - * Note: This function can be used in g_spawn_* as GSpawnChildSetupFunc() - * callback. - */ -void -nm_unblock_posix_signals (gpointer user_data) -{ - sigset_t *user_sigset = (sigset_t *) user_data; - - if (user_sigset != NULL) { - pthread_sigmask (SIG_UNBLOCK, user_sigset, NULL); - } else { - const sigset_t *orig_sig_mask = nm_get_original_signal_mask (); - pthread_sigmask (SIG_SETMASK, orig_sig_mask, NULL); - } -} - diff --git a/src/posix-signals/nm-posix-signals.h b/src/posix-signals/nm-posix-signals.h deleted file mode 100644 index 81be5e1c..00000000 --- a/src/posix-signals/nm-posix-signals.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- 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 - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2012 Red Hat, Inc. - */ - -#ifndef NM_POSIX_SIGNALS_H -#define NM_POSIX_SIGNALS_H - -#include -#include - -/* - * This function can be used in g_spawn_* as GSpawnChildSetupFunc() - * callback. - */ -void nm_unblock_posix_signals (gpointer user_data); - -void nm_save_original_signal_mask (sigset_t sig_mask); -const sigset_t *nm_get_original_signal_mask (void); - -#endif /* NM_POSIX_SIGNALS_H */ diff --git a/src/ppp-manager/Makefile.am b/src/ppp-manager/Makefile.am index 46fc9138..fd2fe76b 100644 --- a/src/ppp-manager/Makefile.am +++ b/src/ppp-manager/Makefile.am @@ -1,11 +1,12 @@ if WITH_PPP AM_CPPFLAGS = \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) pppd_plugindir = $(PPPD_PLUGIN_DIR) @@ -19,8 +20,7 @@ nm_pppd_plugin_la_SOURCES = \ nm_pppd_plugin_la_LDFLAGS = -module -avoid-version nm_pppd_plugin_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + -ldl endif diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in index 731a9459..775e4b5a 100644 --- a/src/ppp-manager/Makefile.in +++ b/src/ppp-manager/Makefile.in @@ -131,9 +131,7 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = \ -@WITH_PPP_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@WITH_PPP_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__nm_pppd_plugin_la_SOURCES_DIST = nm-pppd-plugin.c nm-pppd-plugin.h \ nm-ppp-status.h @WITH_PPP_TRUE@am_nm_pppd_plugin_la_OBJECTS = nm-pppd-plugin.lo @@ -217,6 +215,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -340,6 +340,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -359,6 +360,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -385,7 +387,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -465,11 +467,12 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @WITH_PPP_TRUE@AM_CPPFLAGS = \ -@WITH_PPP_TRUE@ -I${top_builddir}/include \ @WITH_PPP_TRUE@ -I${top_srcdir}/include \ +@WITH_PPP_TRUE@ -I${top_srcdir}/libnm-core \ +@WITH_PPP_TRUE@ -I${top_builddir}/libnm-core \ @WITH_PPP_TRUE@ -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ +@WITH_PPP_TRUE@ -DNETWORKMANAGER_COMPILATION \ @WITH_PPP_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -@WITH_PPP_TRUE@ $(DBUS_CFLAGS) \ @WITH_PPP_TRUE@ $(GLIB_CFLAGS) @WITH_PPP_TRUE@pppd_plugindir = $(PPPD_PLUGIN_DIR) @@ -481,9 +484,8 @@ with_valgrind = @with_valgrind@ @WITH_PPP_TRUE@nm_pppd_plugin_la_LDFLAGS = -module -avoid-version @WITH_PPP_TRUE@nm_pppd_plugin_la_LIBADD = \ -@WITH_PPP_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@WITH_PPP_TRUE@ $(DBUS_LIBS) \ -@WITH_PPP_TRUE@ $(GLIB_LIBS) +@WITH_PPP_TRUE@ $(GLIB_LIBS) \ +@WITH_PPP_TRUE@ -ldl all: all-am diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index e856fc19..4fac96dc 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -19,7 +19,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #include @@ -41,18 +41,14 @@ #endif #include -#include "NetworkManager.h" +#include "NetworkManagerUtils.h" #include "nm-glib-compat.h" #include "nm-ppp-manager.h" -#include "nm-setting-connection.h" -#include "nm-setting-ppp.h" -#include "nm-setting-pppoe.h" -#include "nm-setting-adsl.h" -#include "nm-setting-gsm.h" -#include "nm-setting-cdma.h" #include "nm-dbus-manager.h" #include "nm-logging.h" #include "nm-posix-signals.h" +#include "nm-platform.h" +#include "nm-core-internal.h" static void impl_ppp_manager_need_secrets (NMPPPManager *manager, DBusGMethodInvocation *context); @@ -65,6 +61,10 @@ static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config, GError **err); +static gboolean impl_ppp_manager_set_ip6_config (NMPPPManager *manager, + GHashTable *config, + GError **err); + #include "nm-ppp-manager-glue.h" static void _ppp_cleanup (NMPPPManager *manager); @@ -99,6 +99,7 @@ G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, G_TYPE_OBJECT) enum { STATE_CHANGED, IP4_CONFIG, + IP6_CONFIG, STATS, LAST_SIGNAL @@ -112,24 +113,10 @@ enum { LAST_PROP }; -typedef enum { - NM_PPP_MANAGER_ERROR_UNKOWN -} NMPPPManagerError; - -GQuark -nm_ppp_manager_error_quark (void) -{ - static GQuark quark; - - if (!quark) - quark = g_quark_from_static_string ("nm_ppp_manager_error"); - - return quark; -} - static void nm_ppp_manager_init (NMPPPManager *manager) { + NM_PPP_MANAGER_GET_PRIVATE (manager)->monitor_fd = -1; } static void @@ -218,11 +205,10 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) /* Properties */ g_object_class_install_property (object_class, PROP_PARENT_IFACE, - g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, - "ParentIface", - "Parent interface", + g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[STATE_CHANGED] = @@ -244,6 +230,14 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) G_TYPE_STRING, G_TYPE_OBJECT); + signals[IP6_CONFIG] = + g_signal_new ("ip6-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, ip6_config), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_OBJECT); + signals[STATS] = g_signal_new ("stats", G_OBJECT_CLASS_TYPE (object_class), @@ -299,8 +293,12 @@ monitor_stats (NMPPPManager *manager) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + /* already monitoring */ + if (priv->monitor_fd >= 0) + return; + priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); - if (priv->monitor_fd > 0) { + if (priv->monitor_fd >= 0) { g_warn_if_fail (priv->monitor_id == 0); if (priv->monitor_id) g_source_remove (priv->monitor_id); @@ -370,7 +368,8 @@ extract_details_from_connection (NMConnection *connection, setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { - g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, + /* This shouldn't ever happen */ + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "Missing type-specific setting; no secrets could be found."); return FALSE; } @@ -425,7 +424,7 @@ ppp_secrets_cb (NMActRequest *req, /* This is sort of a hack but... * pppd plugin only ever needs username and password. Passing the full * connection there would mean some bloat: the plugin would need to link - * against libnm-util just to parse this. So instead, let's just send what + * against libnm just to parse this. So instead, let's just send what * it needs. */ dbus_g_method_return (priv->pending_secrets_context, username, password); @@ -447,7 +446,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, guint32 tries; GPtrArray *hints = NULL; GError *error = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; connection = nm_act_request_get_connection (priv->act_req); @@ -473,7 +472,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, */ tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); if (tries > 1) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, priv->secrets_setting_name, @@ -497,20 +496,52 @@ static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, return TRUE; } +static gboolean +set_ip_config_common (NMPPPManager *self, + GHashTable *hash, + const char *iface_prop, + guint32 *out_mtu) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); + NMConnection *connection; + NMSettingPpp *s_ppp; + GValue *val; + + val = g_hash_table_lookup (hash, iface_prop); + if (!val || !G_VALUE_HOLDS_STRING (val)) { + nm_log_err (LOGD_PPP, "no interface received!"); + return FALSE; + } + if (priv->ip_iface == NULL) + priv->ip_iface = g_value_dup_string (val); + + /* Got successful IP config; obviously the secrets worked */ + connection = nm_act_request_get_connection (priv->act_req); + g_assert (connection); + g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); + + /* Get any custom MTU */ + s_ppp = nm_connection_get_setting_ppp (connection); + if (s_ppp && out_mtu) + *out_mtu = nm_setting_ppp_get_mtu (s_ppp); + + monitor_stats (self); + return TRUE; +} + static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config_hash, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); - NMConnection *connection; - NMSettingPPP *s_ppp; NMIP4Config *config; NMPlatformIP4Address address; GValue *val; int i; + guint32 mtu = 0; - nm_log_info (LOGD_PPP, "PPP manager(IP Config Get) reply received."); + nm_log_info (LOGD_PPP, "PPP manager (IPv4 Config Get) reply received."); remove_timeout_handler (manager); @@ -533,7 +564,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, address.plen = g_value_get_uint (val); if (address.address && address.plen) { - address.source = NM_PLATFORM_SOURCE_PPP; + address.source = NM_IP_CONFIG_SOURCE_PPP; nm_ip4_config_add_address (config, &address); } else { nm_log_err (LOGD_PPP, "invalid IPv4 address received!"); @@ -556,35 +587,89 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, nm_ip4_config_add_wins (config, g_array_index (wins, guint, i)); } - val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_INTERFACE); - if (!val || !G_VALUE_HOLDS_STRING (val)) { - nm_log_err (LOGD_PPP, "no interface received!"); + if (!set_ip_config_common (manager, config_hash, NM_PPP_IP4_CONFIG_INTERFACE, &mtu)) goto out; + + if (mtu) + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_PPP); + + /* Push the IP4 config up to the device */ + g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); + +out: + g_object_unref (config); + return TRUE; +} + +/* Converts the named Interface Identifier item to an IPv6 LL address and + * returns the IID. + */ +static gboolean +iid_value_to_ll6_addr (GHashTable *hash, + const char *prop, + struct in6_addr *out_addr, + NMUtilsIPv6IfaceId *out_iid) +{ + GValue *val; + guint64 iid; + + val = g_hash_table_lookup (hash, prop); + if (!val || !G_VALUE_HOLDS (val, G_TYPE_UINT64)) { + nm_log_dbg (LOGD_PPP, "pppd plugin property '%s' missing or not a uint64", prop); + return FALSE; } - priv->ip_iface = g_value_dup_string (val); - /* Got successful IP4 config; obviously the secrets worked */ - connection = nm_act_request_get_connection (priv->act_req); - g_assert (connection); - g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); + iid = g_value_get_uint64 (val); + g_return_val_if_fail (iid != 0, FALSE); - /* Merge in custom MTU */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - guint32 mtu = nm_setting_ppp_get_mtu (s_ppp); + /* Construct an IPv6 LL address from the interface identifier. See + * http://tools.ietf.org/html/rfc4291#section-2.5.1 (IPv6) and + * http://tools.ietf.org/html/rfc5072#section-4.1 (IPv6 over PPP). + */ + memset (out_addr->s6_addr, 0, sizeof (out_addr->s6_addr)); + 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); + return TRUE; +} - if (mtu) - nm_ip4_config_set_mtu (config, mtu); +static gboolean +impl_ppp_manager_set_ip6_config (NMPPPManager *manager, + GHashTable *hash, + GError **err) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + NMIP6Config *config; + NMPlatformIP6Address addr; + struct in6_addr a; + NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + + nm_log_info (LOGD_PPP, "PPP manager (IPv6 Config Get) reply received."); + + remove_timeout_handler (manager); + + config = nm_ip6_config_new (); + + memset (&addr, 0, sizeof (addr)); + addr.plen = 64; + + if (iid_value_to_ll6_addr (hash, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) { + nm_ip6_config_set_gateway (config, &a); + addr.peer_address = a; } - /* Push the IP4 config up to the device */ - g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); + if (iid_value_to_ll6_addr (hash, NM_PPP_IP6_CONFIG_OUR_IID, &addr.address, &iid)) { + nm_ip6_config_add_address (config, &addr); - monitor_stats (manager); + if (set_ip_config_common (manager, hash, NM_PPP_IP6_CONFIG_INTERFACE, NULL)) { + /* Push the IPv6 config and interface identifier up to the device */ + g_signal_emit (manager, signals[IP6_CONFIG], 0, priv->ip_iface, &iid, config); + } + } else + nm_log_err (LOGD_PPP, "invalid IPv6 address received!"); - out: g_object_unref (config); - return TRUE; } @@ -647,36 +732,6 @@ nm_cmd_line_add_int (NMCmdLine *cmd, int i) /*******************************************/ -static const char *pppd_binary_paths[] = { - PPPD_PATH, - "/usr/local/sbin/pppd", - "/usr/sbin/pppd", - "/sbin/pppd", - NULL -}; - -static const char *pppoe_binary_paths[] = { - PPPOE_PATH, - "/usr/local/sbin/pppoe", - "/usr/sbin/pppoe", - "/sbin/pppoe", - NULL -}; - -static inline const char * -nm_find_binary (const char *paths[]) -{ - const char **binary = paths; - - while (*binary != NULL) { - if (**binary && g_file_test (*binary, G_FILE_TEST_EXISTS)) - break; - binary++; - } - - return *binary; -} - static void ppp_exit_code (guint pppd_exit_status, GPid pid) { @@ -789,34 +844,28 @@ pppd_timed_out (gpointer data) static NMCmdLine * create_pppd_cmd_line (NMPPPManager *self, - NMSettingPPP *setting, - NMSettingPPPOE *pppoe, + NMSettingPpp *setting, + NMSettingPppoe *pppoe, NMSettingAdsl *adsl, const char *ppp_name, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - const char *pppd_binary, *pppoe_binary = NULL; + const char *pppd_binary = NULL, *pppoe_binary = NULL; NMCmdLine *cmd; gboolean ppp_debug; g_return_val_if_fail (setting != NULL, NULL); - pppd_binary = nm_find_binary (pppd_binary_paths); - if (!pppd_binary) { - g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, - "Could not find pppd binary."); + pppd_binary = nm_utils_find_helper ("pppd", NULL, err); + if (!pppd_binary) return NULL; - } if ( pppoe || (adsl && strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) { - pppoe_binary = nm_find_binary (pppoe_binary_paths); - if (!pppoe_binary) { - g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, - "Could not find pppoe binary."); + pppoe_binary = nm_utils_find_helper ("pppoe", NULL, err); + if (!pppoe_binary) return NULL; - } } /* Create pppd command line */ @@ -888,7 +937,7 @@ create_pppd_cmd_line (NMPPPManager *self, if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_LLC) == 0) nm_cmd_line_add_string (cmd, "llc-encaps"); - else if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0) + else /*if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0)*/ nm_cmd_line_add_string (cmd, "vc-encaps"); } else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { @@ -992,7 +1041,7 @@ pppd_child_setup (gpointer user_data G_GNUC_UNUSED) } static void -pppoe_fill_defaults (NMSettingPPP *setting) +pppoe_fill_defaults (NMSettingPpp *setting) { if (!nm_setting_ppp_get_mtu (setting)) g_object_set (setting, NM_SETTING_PPP_MTU, (guint32) 1492, NULL); @@ -1005,7 +1054,7 @@ pppoe_fill_defaults (NMSettingPPP *setting) NM_SETTING_PPP_NODEFLATE, TRUE, NULL); - /* FIXME: These commented settings should be set as well, update NMSettingPPP first. */ + /* FIXME: These commented settings should be set as well, update NMSettingPpp first. */ #if 0 setting->noipdefault = TRUE; setting->default_asyncmap = TRUE; @@ -1027,9 +1076,9 @@ nm_ppp_manager_start (NMPPPManager *manager, { NMPPPManagerPrivate *priv; NMConnection *connection; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; gboolean s_ppp_created = FALSE; - NMSettingPPPOE *pppoe_setting; + NMSettingPppoe *pppoe_setting; NMSettingAdsl *adsl_setting; NMCmdLine *ppp_cmd; char *cmd_str; @@ -1044,8 +1093,8 @@ nm_ppp_manager_start (NMPPPManager *manager, #if !WITH_PPP /* PPP support disabled */ g_set_error_literal (err, - NM_PPP_MANAGER_ERROR, - NM_PPP_MANAGER_ERROR_UNKOWN, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "PPP support is not enabled."); return FALSE; #endif @@ -1110,22 +1159,6 @@ out: return priv->pid > 0; } -static gboolean -ensure_killed (gpointer data) -{ - int pid = GPOINTER_TO_INT (data); - - if (kill (pid, 0) == 0) - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_PPP, "waiting for pppd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_PPP, "pppd pid %d cleaned up", pid); - - return FALSE; -} - static void _ppp_cleanup (NMPPPManager *manager) { @@ -1142,11 +1175,11 @@ _ppp_cleanup (NMPPPManager *manager) priv->monitor_id = 0; } - if (priv->monitor_fd) { + if (priv->monitor_fd >= 0) { /* Get the stats one last time */ monitor_cb (manager); close (priv->monitor_fd); - priv->monitor_fd = 0; + priv->monitor_fd = -1; } if (priv->ppp_timeout_handler) { @@ -1160,17 +1193,7 @@ _ppp_cleanup (NMPPPManager *manager) } if (priv->pid) { - if (kill (priv->pid, SIGTERM) == 0) - g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid)); - else { - kill (priv->pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_PPP, "waiting for pppd pid %d to exit", priv->pid); - waitpid (priv->pid, NULL, 0); - nm_log_dbg (LOGD_PPP, "pppd pid %d cleaned up", priv->pid); - } - + nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_PPP, "pppd", 2000, NULL, NULL); priv->pid = 0; } } diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 1b4bc188..84be76d0 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2008 - 2010 Red Hat, Inc. */ -#ifndef NM_PPP_MANAGER_H -#define NM_PPP_MANAGER_H +#ifndef __NETWORKMANAGER_PPP_MANAGER_H__ +#define __NETWORKMANAGER_PPP_MANAGER_H__ #include #include @@ -29,7 +29,9 @@ #include "nm-activation-request.h" #include "nm-connection.h" #include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-pppd-plugin.h" +#include "NetworkManagerUtils.h" #define NM_TYPE_PPP_MANAGER (nm_ppp_manager_get_type ()) #define NM_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPP_MANAGER, NMPPPManager)) @@ -50,6 +52,10 @@ typedef struct { /* Signals */ void (*state_changed) (NMPPPManager *manager, NMPPPStatus status); void (*ip4_config) (NMPPPManager *manager, const char *iface, NMIP4Config *config); + void (*ip6_config) (NMPPPManager *manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config); void (*stats) (NMPPPManager *manager, guint32 in_bytes, guint32 out_bytes); } NMPPPManagerClass; @@ -64,9 +70,4 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager, GError **err); -#define NM_PPP_MANAGER_ERROR nm_ppp_manager_error_quark() -#define NM_TYPE_PPP_MANAGER_ERROR (nm_ppp_manager_error_get_type ()) - -GQuark nm_ppp_manager_error_quark (void); - -#endif /* NM_PPP_MANAGER_H */ +#endif /* __NETWORKMANAGER_PPP_MANAGER_H__ */ diff --git a/src/ppp-manager/nm-ppp-status.h b/src/ppp-manager/nm-ppp-status.h index cfc7c393..391b5aa9 100644 --- a/src/ppp-manager/nm-ppp-status.h +++ b/src/ppp-manager/nm-ppp-status.h @@ -19,8 +19,8 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#ifndef NM_PPP_STATUS_H -#define NM_PPP_STATUS_H +#ifndef __NETWORKMANAGER_PPP_STATUS_H__ +#define __NETWORKMANAGER_PPP_STATUS_H__ typedef enum { NM_PPP_STATUS_UNKNOWN, @@ -40,4 +40,4 @@ typedef enum { NM_PPP_STATUS_MASTER } NMPPPStatus; -#endif /* NM_PPP_STATUS_H */ +#endif /* __NETWORKMANAGER_PPP_STATUS_H__ */ diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c index e6ee86f7..d5e8d707 100644 --- a/src/ppp-manager/nm-pppd-plugin.c +++ b/src/ppp-manager/nm-pppd-plugin.c @@ -19,6 +19,8 @@ * Copyright (C) 2008 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -26,20 +28,22 @@ #include #include #include -#include -#include -#include +#include +#include + +#define INET6 +#include +#include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-pppd-plugin.h" #include "nm-ppp-status.h" -#include "nm-dbus-glib-types.h" int plugin_init (void); char pppd_version[] = VERSION; -static DBusGProxy *proxy = NULL; +static GDBusProxy *proxy = NULL; static void nm_phasechange (void *data, int arg) @@ -47,7 +51,7 @@ nm_phasechange (void *data, int arg) NMPPPStatus ppp_status = NM_PPP_STATUS_UNKNOWN; char *ppp_phase; - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); switch (arg) { case PHASE_DEAD: @@ -114,56 +118,24 @@ nm_phasechange (void *data, int arg) ppp_phase); if (ppp_status != NM_PPP_STATUS_UNKNOWN) { - dbus_g_proxy_call_no_reply (proxy, "SetState", - G_TYPE_UINT, ppp_status, G_TYPE_INVALID, - G_TYPE_INVALID); + g_dbus_proxy_call (proxy, + "SetState", + g_variant_new ("(u)", ppp_status), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); } } -static GValue * -str_to_gvalue (const char *str) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - - return val; -} - -static GValue * -uint_to_gvalue (guint32 i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UINT); - g_value_set_uint (val, i); - - return val; -} - -static void -value_destroy (gpointer data) -{ - GValue *val = (GValue *) data; - - g_value_unset (val); - g_slice_free (GValue, val); -} - static void nm_ip_up (void *data, int arg) { ipcp_options opts = ipcp_gotoptions[0]; ipcp_options peer_opts = ipcp_hisoptions[0]; - GHashTable *hash; - GArray *array; - GValue *val; + GVariantBuilder builder; guint32 pppd_made_up_address = htonl (0x0a404040 + ifunit); - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); g_message ("nm-ppp-plugin: (%s): ip-up event", __func__); @@ -173,70 +145,122 @@ nm_ip_up (void *data, int arg) return; } - hash = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, value_destroy); + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_INTERFACE, - str_to_gvalue (ifname)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_INTERFACE, + g_variant_new_string (ifname)); - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_ADDRESS, - uint_to_gvalue (opts.ouraddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_ADDRESS, + g_variant_new_uint32 (opts.ouraddr)); /* Prefer the peer options remote address first, _unless_ pppd made the * address up, at which point prefer the local options remote address, * and if that's not right, use the made-up address as a last resort. */ if (peer_opts.hisaddr && (peer_opts.hisaddr != pppd_made_up_address)) { - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (peer_opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (peer_opts.hisaddr)); } else if (opts.hisaddr) { - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (opts.hisaddr)); } else if (peer_opts.hisaddr == pppd_made_up_address) { /* As a last resort, use the made-up address */ - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (peer_opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (peer_opts.ouraddr)); } - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_PREFIX, uint_to_gvalue (32)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_PREFIX, + g_variant_new_uint32 (32)); if (opts.dnsaddr[0] || opts.dnsaddr[1]) { - array = g_array_new (FALSE, FALSE, sizeof (guint32)); + guint32 dns[2]; + int len = 0; if (opts.dnsaddr[0]) - g_array_append_val (array, opts.dnsaddr[0]); + dns[len++] = opts.dnsaddr[0]; if (opts.dnsaddr[1]) - g_array_append_val (array, opts.dnsaddr[1]); + dns[len++] = opts.dnsaddr[1]; - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UINT_ARRAY); - g_value_set_boxed (val, array); - - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_DNS, val); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_DNS, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + dns, len, sizeof (guint32))); } if (opts.winsaddr[0] || opts.winsaddr[1]) { - array = g_array_new (FALSE, FALSE, sizeof (guint32)); + guint32 wins[2]; + int len = 0; if (opts.winsaddr[0]) - g_array_append_val (array, opts.winsaddr[0]); + wins[len++] = opts.winsaddr[0]; if (opts.winsaddr[1]) - g_array_append_val (array, opts.winsaddr[1]); - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UINT_ARRAY); - g_value_set_boxed (val, array); + wins[len++] = opts.winsaddr[1]; - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_WINS, val); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_WINS, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + wins, len, sizeof (guint32))); } - g_message ("nm-ppp-plugin: (%s): sending Ip4Config to NetworkManager...", __func__); + g_message ("nm-ppp-plugin: (%s): sending IPv4 config to NetworkManager...", __func__); + + g_dbus_proxy_call (proxy, + "SetIp4Config", + g_variant_new ("(a{sv})", &builder), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); +} + +static GVariant * +eui64_to_variant (eui64_t eui) +{ + guint64 iid; + + G_STATIC_ASSERT (sizeof (iid) == sizeof (eui)); - dbus_g_proxy_call_no_reply (proxy, "SetIp4Config", - DBUS_TYPE_G_MAP_OF_VARIANT, hash, G_TYPE_INVALID, - G_TYPE_INVALID); + memcpy (&iid, &eui, sizeof (eui)); + return g_variant_new_uint64 (iid); +} - g_hash_table_destroy (hash); +static void +nm_ip6_up (void *data, int arg) +{ + ipv6cp_options *ho = &ipv6cp_hisoptions[0]; + ipv6cp_options *go = &ipv6cp_gotoptions[0]; + GVariantBuilder builder; + + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + + g_message ("nm-ppp-plugin: (%s): ip6-up event", __func__); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_INTERFACE, + g_variant_new_string (ifname)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_OUR_IID, + eui64_to_variant (go->ourid)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_PEER_IID, + eui64_to_variant (ho->hisid)); + + /* DNS is done via DHCPv6 or router advertisements */ + + g_message ("nm-ppp-plugin: (%s): sending IPv6 config to NetworkManager...", __func__); + + g_dbus_proxy_call (proxy, + "SetIp6Config", + g_variant_new ("(a{sv})", &builder), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); } static int @@ -254,9 +278,10 @@ get_pap_check (void) static int get_credentials (char *username, char *password) { - char *my_username = NULL; - char *my_password = NULL; + const char *my_username = NULL; + const char *my_password = NULL; size_t len; + GVariant *ret; GError *err = NULL; if (!password) { @@ -266,15 +291,16 @@ get_credentials (char *username, char *password) } g_return_val_if_fail (username, -1); - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), -1); + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), -1); g_message ("nm-ppp-plugin: (%s): passwd-hook, requesting credentials...", __func__); - if (!dbus_g_proxy_call (proxy, "NeedSecrets", &err, - G_TYPE_INVALID, - G_TYPE_STRING, &my_username, - G_TYPE_STRING, &my_password, - G_TYPE_INVALID)) { + ret = g_dbus_proxy_call_sync (proxy, + "NeedSecrets", + NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &err); + if (!ret) { g_warning ("nm-ppp-plugin: (%s): could not get secrets: (%d) %s", __func__, err ? err->code : -1, @@ -285,14 +311,14 @@ get_credentials (char *username, char *password) g_message ("nm-ppp-plugin: (%s): got credentials from NetworkManager", __func__); + g_variant_get (ret, "(&s&s)", &my_username, &my_password); + if (my_username) { len = strlen (my_username) + 1; len = len < MAXNAMELEN ? len : MAXNAMELEN; strncpy (username, my_username, len); username[len - 1] = '\0'; - - g_free (my_username); } if (my_password) { @@ -301,17 +327,17 @@ get_credentials (char *username, char *password) strncpy (password, my_password, len); password[len - 1] = '\0'; - - g_free (my_password); } + g_variant_unref (ret); + return 1; } static void nm_exit_notify (void *data, int arg) { - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); g_message ("nm-ppp-plugin: (%s): cleaning up", __func__); @@ -319,10 +345,31 @@ nm_exit_notify (void *data, int arg) proxy = NULL; } +static void +add_ip6_notifier (void) +{ + static struct notifier **notifier = NULL; + static gsize load_once = 0; + + if (g_once_init_enter (&load_once)) { + void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + + if (handle) { + notifier = dlsym (handle, "ipv6_up_notifier"); + dlclose (handle); + } + g_once_init_leave (&load_once, 1); + } + if (notifier) + add_notifier (notifier, nm_ip6_up, NULL); + else + g_message ("nm-ppp-plugin: no IPV6CP notifier support; IPv6 not available"); +} + int plugin_init (void) { - DBusGConnection *bus; + GDBusConnection *bus; GError *err = NULL; #if !GLIB_CHECK_VERSION (2, 35, 0) @@ -331,12 +378,10 @@ plugin_init (void) g_message ("nm-ppp-plugin: (%s): initializing", __func__); - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &err); if (!bus) { - g_warning ("nm-pppd-plugin: (%s): couldn't connect to system bus: (%d) %s", - __func__, - err ? err->code : -1, - err && err->message ? err->message : "(unknown)"); + g_warning ("nm-pppd-plugin: (%s): couldn't connect to system bus: %s", + __func__, err->message); g_error_free (err); return -1; } @@ -344,9 +389,21 @@ plugin_init (void) /* NM passes in the object path of the corresponding PPPManager * object as the 'ipparam' argument to pppd. */ - proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE, ipparam, NM_DBUS_INTERFACE_PPP); - - dbus_g_connection_unref (bus); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + NM_DBUS_SERVICE, + ipparam, + NM_DBUS_INTERFACE_PPP, + NULL, &err); + g_object_unref (bus); + + if (!proxy) { + g_warning ("nm-pppd-plugin: (%s): couldn't create D-Bus proxy: %s", + __func__, err->message); + g_error_free (err); + return -1; + } chap_passwd_hook = get_credentials; chap_check_hook = get_chap_check; @@ -356,6 +413,7 @@ plugin_init (void) add_notifier (&phasechange, nm_phasechange, NULL); add_notifier (&ip_up_notifier, nm_ip_up, NULL); add_notifier (&exitnotify, nm_exit_notify, proxy); + add_ip6_notifier (); return 0; } diff --git a/src/ppp-manager/nm-pppd-plugin.h b/src/ppp-manager/nm-pppd-plugin.h index 95a2a182..2c3073e4 100644 --- a/src/ppp-manager/nm-pppd-plugin.h +++ b/src/ppp-manager/nm-pppd-plugin.h @@ -16,14 +16,21 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. */ #define NM_DBUS_INTERFACE_PPP "org.freedesktop.NetworkManager.PPP" #define NM_PPP_IP4_CONFIG_INTERFACE "interface" -#define NM_PPP_IP4_CONFIG_ADDRESS "address" -#define NM_PPP_IP4_CONFIG_PREFIX "prefix" -#define NM_PPP_IP4_CONFIG_GATEWAY "gateway" -#define NM_PPP_IP4_CONFIG_DNS "dns" -#define NM_PPP_IP4_CONFIG_WINS "wins" +#define NM_PPP_IP4_CONFIG_ADDRESS "address" +#define NM_PPP_IP4_CONFIG_PREFIX "prefix" +#define NM_PPP_IP4_CONFIG_GATEWAY "gateway" +#define NM_PPP_IP4_CONFIG_DNS "dns" +#define NM_PPP_IP4_CONFIG_WINS "wins" + +#define NM_PPP_IP6_CONFIG_INTERFACE "interface" +#define NM_PPP_IP6_CONFIG_OUR_IID "our-iid" +#define NM_PPP_IP6_CONFIG_PEER_IID "peer-iid" + +#define DBUS_TYPE_EUI64 (dbus_g_type_get_collection ("GByteArray", G_TYPE_UINT8)) + diff --git a/src/rdisc/Makefile.in b/src/rdisc/Makefile.in index bee23500..47a71931 100644 --- a/src/rdisc/Makefile.in +++ b/src/rdisc/Makefile.in @@ -189,6 +189,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -312,6 +314,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -331,6 +334,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -357,7 +361,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ diff --git a/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c index bdd207ca..e631f28d 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/rdisc/nm-fake-rdisc.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ +#include "config.h" + #include #include diff --git a/src/rdisc/nm-fake-rdisc.h b/src/rdisc/nm-fake-rdisc.h index 248283b2..b4eff7ec 100644 --- a/src/rdisc/nm-fake-rdisc.h +++ b/src/rdisc/nm-fake-rdisc.h @@ -18,8 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_FAKE_RDISC_H -#define NM_FAKE_RDISC_H +#ifndef __NETWORKMANAGER_FAKE_RDISC_H__ +#define __NETWORKMANAGER_FAKE_RDISC_H__ #include "nm-rdisc.h" @@ -46,4 +46,4 @@ GType nm_fake_rdisc_get_type (void); NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname); -#endif /* NM_FAKE_RDISC_H */ +#endif /* __NETWORKMANAGER_FAKE_RDISC_H__ */ diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index cf0267d1..ff1bd33d 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ +#include "config.h" + #include #include /* stdarg.h included because of a bug in ndp.h */ @@ -28,6 +30,7 @@ #include "NetworkManagerUtils.h" #include "nm-logging.h" +#include "nm-platform.h" #define debug(...) nm_log_dbg (LOGD_IP6, __VA_ARGS__) #define warning(...) nm_log_warn (LOGD_IP6, __VA_ARGS__) @@ -39,7 +42,8 @@ typedef struct { guint send_rs_id; GIOChannel *event_channel; guint event_id; - guint timeout_id; + guint timeout_id; /* prefix/dns/etc lifetime timeout */ + guint ra_timeout_id; /* first RA timeout */ int solicitations_left; } NMLNDPRDiscPrivate; @@ -174,8 +178,15 @@ add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { - gboolean changed = item->timestamp != new->timestamp || - item->lifetime != new->lifetime; + gboolean changed; + + if (new->lifetime == 0) { + g_array_remove_index (rdisc->dns_servers, i); + return TRUE; + } + + changed = (item->timestamp != new->timestamp || + item->lifetime != new->lifetime); if (changed) { item->timestamp = new->timestamp; item->lifetime = new->lifetime; @@ -184,10 +195,6 @@ add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) } } - /* DNS server should no longer be used */ - if (new->lifetime == 0) - return FALSE; - g_array_insert_val (rdisc->dns_servers, i, *new); return TRUE; } @@ -203,8 +210,15 @@ add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); if (!g_strcmp0 (item->domain, new->domain)) { - gboolean changed = item->timestamp != new->timestamp || - item->lifetime != new->lifetime; + gboolean changed; + + if (new->lifetime == 0) { + g_array_remove_index (rdisc->dns_domains, i); + return TRUE; + } + + changed = (item->timestamp != new->timestamp || + item->lifetime != new->lifetime); if (changed) { item->timestamp = new->timestamp; item->lifetime = new->lifetime; @@ -213,10 +227,6 @@ add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) } } - /* Domain should no longer be used */ - if (new->lifetime == 0) - return FALSE; - g_array_insert_val (rdisc->dns_domains, i, *new); item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); item->domain = g_strdup (new->domain); @@ -433,42 +443,38 @@ translate_preference (enum ndp_route_preference preference) } static void -fill_address_from_mac (struct in6_addr *address, const char *mac) +clear_rs_timeout (NMLNDPRDisc *rdisc) { - unsigned char *identifier = address->s6_addr + 8; + NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - if (!mac) - return; + if (priv->send_rs_id) { + g_source_remove (priv->send_rs_id); + priv->send_rs_id = 0; + } +} - /* Translate 48-bit MAC address to a 64-bit modified interface identifier - * and write it to the second half of the IPv6 address. - * - * See http://tools.ietf.org/html/rfc3513#page-21 - */ - memcpy (identifier, mac, 3); - identifier[0] ^= 0x02; - identifier[3] = 0xff; - identifier[4] = 0xfe; - memcpy (identifier + 5, mac + 3, 3); +static void +clear_ra_timeout (NMLNDPRDisc *rdisc) +{ + NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); + + if (priv->ra_timeout_id) { + g_source_remove (priv->ra_timeout_id); + priv->ra_timeout_id = 0; + } } static int receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) { NMRDisc *rdisc = (NMRDisc *) user_data; - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); NMRDiscConfigMap changed = 0; - size_t lladdrlen = 0; - const char *lladdr = NULL; struct ndp_msgra *msgra = ndp_msgra (msg); NMRDiscGateway gateway; guint32 now = nm_utils_get_monotonic_timestamp_s (); int offset; int hop_limit; - if (rdisc->lladdr) - lladdr = g_bytes_get_data (rdisc->lladdr, &lladdrlen); - /* Router discovery is subject to the following RFC documents: * * http://tools.ietf.org/html/rfc4861 @@ -482,10 +488,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ debug ("(%s): received router advertisement at %u", rdisc->ifname, now); - if (priv->send_rs_id) { - g_source_remove (priv->send_rs_id); - priv->send_rs_id = 0; - } + clear_ra_timeout (NM_LNDP_RDISC (rdisc)); + clear_rs_timeout (NM_LNDP_RDISC (rdisc)); /* DHCP level: * @@ -541,7 +545,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) /* Address */ if (ndp_msg_opt_prefix_flag_auto_addr_conf (msg, offset)) { - if (route.plen == 64 && lladdrlen == 6) { + if (route.plen == 64 && rdisc->iid.id) { memset (&address, 0, sizeof (address)); address.address = route.network; address.timestamp = now; @@ -550,7 +554,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) if (address.preferred > address.lifetime) address.preferred = address.lifetime; - fill_address_from_mac (&address.address, lladdr); + /* Add the Interface Identifier to the lower 64 bits */ + nm_utils_ipv6_addr_set_interface_identfier (&address.address, rdisc->iid); if (add_address (rdisc, &address)) changed |= NM_RDISC_CONFIG_ADDRESSES; @@ -624,26 +629,45 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) changed |= NM_RDISC_CONFIG_HOP_LIMIT; } + /* MTU */ + ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_MTU) { + guint32 mtu = ndp_msg_opt_mtu(msg, offset); + if (mtu >= 1280) { + rdisc->mtu = mtu; + changed |= NM_RDISC_CONFIG_MTU; + } else { + /* All sorts of bad things would happen if we accepted this. + * Kernel would set it, but would flush out all IPv6 addresses away + * from the link, even the link-local, and we wouldn't be able to + * listen for further RAs that could fix the MTU. */ + warning ("(%s): MTU too small for IPv6 ignored: %d", rdisc->ifname, mtu); + } + } + check_timestamps (rdisc, now, changed); return 0; } -static void -process_events (NMRDisc *rdisc) +static gboolean +event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) { NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); debug ("(%s): processing libndp events.", rdisc->ifname); ndp_callall_eventfd_handler (priv->ndp); + return G_SOURCE_CONTINUE; } static gboolean -event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) +rdisc_ra_timeout_cb (gpointer user_data) { - process_events (rdisc); + NMLNDPRDisc *rdisc = NM_LNDP_RDISC (user_data); + NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - return TRUE; + priv->ra_timeout_id = 0; + g_signal_emit_by_name (rdisc, NM_RDISC_RA_TIMEOUT); + return G_SOURCE_REMOVE; } static void @@ -651,14 +675,20 @@ start (NMRDisc *rdisc) { NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); int fd = ndp_get_eventfd (priv->ndp); + guint ra_wait_secs; priv->event_channel = g_io_channel_unix_new (fd); priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, rdisc); + clear_ra_timeout (NM_LNDP_RDISC (rdisc)); + ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120); + priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc); + debug ("(%s): scheduling RA timeout in %d seconds", rdisc->ifname, ra_wait_secs); + /* Flush any pending messages to avoid using obsolete information */ - process_events (rdisc); + event_ready (priv->event_channel, 0, rdisc); - ndp_msgrcv_handler_register (priv->ndp, &receive_ra, NDP_MSG_RA, rdisc->ifindex, rdisc); + ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, rdisc->ifindex, rdisc); solicit (rdisc); } @@ -670,21 +700,29 @@ nm_lndp_rdisc_init (NMLNDPRDisc *lndp_rdisc) } static void -nm_lndp_rdisc_finalize (GObject *object) +dispose (GObject *object) { - NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (object); + NMLNDPRDisc *rdisc = NM_LNDP_RDISC (object); + NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); - if (priv->send_rs_id) - g_source_remove (priv->send_rs_id); - if (priv->timeout_id) + clear_rs_timeout (rdisc); + clear_ra_timeout (rdisc); + + if (priv->timeout_id) { g_source_remove (priv->timeout_id); - if (priv->event_channel) - g_io_channel_unref (priv->event_channel); - if (priv->event_id) + priv->timeout_id = 0; + } + + if (priv->event_id) { g_source_remove (priv->event_id); + priv->event_id = 0; + } + g_clear_pointer (&priv->event_channel, g_io_channel_unref); - if (priv->ndp) + if (priv->ndp) { ndp_close (priv->ndp); + priv->ndp = NULL; + } } static void @@ -695,6 +733,6 @@ nm_lndp_rdisc_class_init (NMLNDPRDiscClass *klass) g_type_class_add_private (klass, sizeof (NMLNDPRDiscPrivate)); - object_class->finalize = nm_lndp_rdisc_finalize; + object_class->dispose = dispose; rdisc_class->start = start; } diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h index eb6a1df6..407e1f92 100644 --- a/src/rdisc/nm-lndp-rdisc.h +++ b/src/rdisc/nm-lndp-rdisc.h @@ -18,8 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_LNDP_RDISC_H -#define NM_LNDP_RDISC_H +#ifndef __NETWORKMANAGER_LNDP_RDISC_H__ +#define __NETWORKMANAGER_LNDP_RDISC_H__ #include "nm-rdisc.h" @@ -46,4 +46,4 @@ GType nm_lndp_rdisc_get_type (void); NMRDisc *nm_lndp_rdisc_new (int ifindex, const char *ifname); -#endif /* NM_LNDP_RDISC_H */ +#endif /* __NETWORKMANAGER_LNDP_RDISC_H__ */ diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index 1682924c..8729fa63 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ +#include "config.h" + #include #include @@ -32,6 +34,7 @@ G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT) enum { CONFIG_CHANGED, + RA_TIMEOUT, LAST_SIGNAL }; @@ -40,11 +43,11 @@ static guint signals[LAST_SIGNAL] = { 0 }; /******************************************************************/ void -nm_rdisc_set_lladdr (NMRDisc *rdisc, const char *addr, size_t addrlen) +nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) { - if (rdisc->lladdr) - g_bytes_unref (rdisc->lladdr); - rdisc->lladdr = addr ? g_bytes_new (addr, addrlen) : NULL; + g_return_if_fail (NM_IS_RDISC (rdisc)); + + rdisc->iid = iid; } void @@ -152,7 +155,6 @@ nm_rdisc_init (NMRDisc *rdisc) rdisc->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute)); rdisc->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); rdisc->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); - rdisc->lladdr = NULL; rdisc->hop_limit = 64; } @@ -167,9 +169,6 @@ nm_rdisc_finalize (GObject *object) g_array_unref (rdisc->routes); g_array_unref (rdisc->dns_servers); g_array_unref (rdisc->dns_domains); - - if (rdisc->lladdr) - g_bytes_unref (rdisc->lladdr); } static void @@ -188,4 +187,12 @@ nm_rdisc_class_init (NMRDiscClass *klass) G_STRUCT_OFFSET (NMRDiscClass, config_changed), NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); + + signals[RA_TIMEOUT] = g_signal_new ( + NM_RDISC_RA_TIMEOUT, + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRDiscClass, ra_timeout), + NULL, NULL, NULL, + G_TYPE_NONE, 0); } diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index fba06bc2..2d83f0f0 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -18,14 +18,16 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef NM_RDISC_H -#define NM_RDISC_H +#ifndef __NETWORKMANAGER_RDISC_H__ +#define __NETWORKMANAGER_RDISC_H__ #include #include #include +#include "NetworkManagerUtils.h" + #define NM_TYPE_RDISC (nm_rdisc_get_type ()) #define NM_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_RDISC, NMRDisc)) #define NM_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_RDISC, NMRDiscClass)) @@ -34,6 +36,7 @@ #define NM_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass)) #define NM_RDISC_CONFIG_CHANGED "config-changed" +#define NM_RDISC_RA_TIMEOUT "ra-timeout" typedef enum { NM_RDISC_DHCP_LEVEL_UNKNOWN, @@ -92,6 +95,7 @@ typedef enum { NM_RDISC_CONFIG_DNS_SERVERS = 1 << 4, NM_RDISC_CONFIG_DNS_DOMAINS = 1 << 5, NM_RDISC_CONFIG_HOP_LIMIT = 1 << 6, + NM_RDISC_CONFIG_MTU = 1 << 7, } NMRDiscConfigMap; #define NM_RDISC_MAX_ADDRESSES_DEFAULT 16 @@ -110,7 +114,7 @@ typedef struct { int ifindex; char *ifname; - GBytes *lladdr; + NMUtilsIPv6IfaceId iid; gint32 max_addresses; gint32 rtr_solicitations; gint32 rtr_solicitation_interval; @@ -122,6 +126,7 @@ typedef struct { GArray *dns_servers; GArray *dns_domains; int hop_limit; + guint32 mtu; } NMRDisc; typedef struct { @@ -129,11 +134,12 @@ typedef struct { void (*start) (NMRDisc *rdisc); void (*config_changed) (NMRDisc *rdisc, NMRDiscConfigMap changed); + void (*ra_timeout) (NMRDisc *rdisc); } NMRDiscClass; GType nm_rdisc_get_type (void); -void nm_rdisc_set_lladdr (NMRDisc *rdisc, const char *addr, size_t addrlen); +void nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid); void nm_rdisc_start (NMRDisc *rdisc); -#endif /* NM_RDISC_H */ +#endif /* __NETWORKMANAGER_RDISC_H__ */ diff --git a/src/rdisc/tests/Makefile.am b/src/rdisc/tests/Makefile.am index cf351d61..e6fe1369 100644 --- a/src/rdisc/tests/Makefile.am +++ b/src/rdisc/tests/Makefile.am @@ -1,20 +1,15 @@ AM_CPPFLAGS = \ -I${top_srcdir} \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/posix-signals \ - -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I${srcdir}/.. \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(LIBNDP_CFLAGS) AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) @@ -31,6 +26,5 @@ noinst_PROGRAMS = \ rdisc_SOURCES = \ rdisc.c rdisc_LDADD = \ - $(top_builddir)/src/libNetworkManager.la \ - $(LIBNDP_LIBS) + $(top_builddir)/src/libNetworkManager.la diff --git a/src/rdisc/tests/Makefile.in b/src/rdisc/tests/Makefile.in index 97ade88f..b2ea3c74 100644 --- a/src/rdisc/tests/Makefile.in +++ b/src/rdisc/tests/Makefile.in @@ -105,9 +105,7 @@ CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_rdisc_OBJECTS = rdisc.$(OBJEXT) rdisc_OBJECTS = $(am_rdisc_OBJECTS) -am__DEPENDENCIES_1 = -rdisc_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la \ - $(am__DEPENDENCIES_1) +rdisc_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -182,6 +180,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -305,6 +305,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -324,6 +325,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -350,7 +352,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -432,20 +434,15 @@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I${top_srcdir} \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ -I${top_srcdir}/src \ - -I${top_srcdir}/src/devices \ - -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/platform \ - -I${top_srcdir}/src/posix-signals \ - -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -I${srcdir}/.. \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(LIBNL_CFLAGS) \ $(LIBNDP_CFLAGS) AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) @@ -458,8 +455,7 @@ rdisc_SOURCES = \ rdisc.c rdisc_LDADD = \ - $(top_builddir)/src/libNetworkManager.la \ - $(LIBNDP_LIBS) + $(top_builddir)/src/libNetworkManager.la all: all-am diff --git a/src/rdisc/tests/rdisc.c b/src/rdisc/tests/rdisc.c index 1fdf5b67..d577a63a 100644 --- a/src/rdisc/tests/rdisc.c +++ b/src/rdisc/tests/rdisc.c @@ -18,6 +18,8 @@ * Copyright (C) 2013 Red Hat, Inc. */ +#include "config.h" + #include #include @@ -37,7 +39,6 @@ main (int argc, char **argv) NMRDisc *(*new) (int ifindex, const char *ifname); int ifindex = 1; const char *ifname; - char mac[6] = { 0x02, 0xaa, 0xbb, 0xcc, 0xdd, 0xee }; #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); @@ -69,8 +70,6 @@ main (int argc, char **argv) if (!rdisc) return EXIT_FAILURE; - nm_rdisc_set_lladdr (rdisc, mac, 6); - nm_rdisc_start (rdisc); g_main_loop_run (loop); diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index ae930692..cc4b1943 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -18,7 +18,8 @@ * Copyright (C) 2010 - 2013 Red Hat, Inc. */ -#include +#include "config.h" + #include #include @@ -26,16 +27,21 @@ #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-logging.h" #include "nm-agent-manager.h" #include "nm-secret-agent.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-dbus-glib-types.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" #include "nm-setting-vpn.h" #include "nm-setting-connection.h" #include "nm-enum-types.h" +#include "nm-auth-manager.h" +#include "nm-dbus-manager.h" +#include "nm-session-monitor.h" +#include "nm-simple-connection.h" +#include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -89,20 +95,6 @@ static void impl_agent_manager_unregister (NMAgentManager *self, #include "nm-agent-manager-glue.h" -/********************************************************************/ - -#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ()) - -static GQuark -nm_agent_manager_error_quark (void) -{ - static GQuark ret = 0; - - if (G_UNLIKELY (ret == 0)) - ret = g_quark_from_static_string ("nm-agent-manager-error"); - return ret; -} - /*************************************************************/ static gboolean @@ -285,14 +277,14 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self, NMSecretAgent *agent; NMAuthChain *chain; - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "Unable to determine request sender and UID."); goto done; } - sender_uid = nm_auth_subject_get_uid (subject); + sender_uid = nm_auth_subject_get_unix_process_uid (subject); if ( 0 != sender_uid && !nm_session_monitor_uid_has_session (nm_session_monitor_get (), @@ -300,7 +292,7 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self, NULL, &local)) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, local && local->message ? local->message : "Session not found"); goto done; } @@ -321,7 +313,7 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self, agent = nm_secret_agent_new (context, subject, identifier, capabilities); if (!agent) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, + NM_AGENT_MANAGER_ERROR_FAILED, "Failed to initialize the agent"); goto done; } @@ -339,7 +331,7 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self, priv->chains = g_slist_append (priv->chains, chain); } else { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + NM_AGENT_MANAGER_ERROR_FAILED, "Unable to start agent authentication."); } @@ -373,7 +365,7 @@ impl_agent_manager_unregister (NMAgentManager *self, NULL, NULL)) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "Unable to determine request sender."); goto done; } @@ -524,8 +516,8 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) gulong a_pid, b_pid, requester; /* Prefer agents in the process the request came from */ - requester = nm_auth_subject_get_pid (req->subject); - if (requester != G_MAXULONG) { + if (nm_auth_subject_is_unix_process (req->subject)) { + requester = nm_auth_subject_get_unix_process_pid (req->subject); a_pid = nm_secret_agent_get_pid (a); b_pid = nm_secret_agent_get_pid (b); @@ -567,11 +559,11 @@ request_add_agent (Request *req, NMSecretAgent *agent) return; /* If the request should filter agents by UID, do that now */ - if (!nm_auth_subject_get_internal (req->subject)) { + if (nm_auth_subject_is_unix_process (req->subject)) { uid_t agent_uid, subject_uid; agent_uid = nm_secret_agent_get_owner_uid (agent); - subject_uid = nm_auth_subject_get_uid (req->subject); + subject_uid = nm_auth_subject_get_unix_process_uid (req->subject); if (agent_uid != subject_uid) { nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s " "(uid %ld not required %ld)", @@ -670,7 +662,7 @@ request_start (gpointer user_data) typedef struct { Request parent; - NMSettingsGetSecretsFlags flags; + NMSecretAgentGetSecretsFlags flags; NMConnection *connection; char *setting_name; char **hints; @@ -708,12 +700,12 @@ static gboolean connection_request_add_agent (Request *parent, NMSecretAgent *agent) { ConnectionRequest *req = (ConnectionRequest *) parent; - uid_t agent_uid = nm_secret_agent_get_owner_uid (agent); + NMAuthSubject *subject = nm_secret_agent_get_subject(agent); /* Ensure the caller's username exists in the connection's permissions, * or that the permissions is empty (ie, visible by everyone). */ - if (!nm_auth_uid_in_acl (req->connection, nm_session_monitor_get (), agent_uid, NULL)) { + if (!nm_auth_is_subject_in_acl (req->connection, nm_session_monitor_get (), subject, NULL)) { nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s (not in ACL)", nm_secret_agent_get_description (agent), parent, parent->detail); @@ -730,7 +722,7 @@ connection_request_new_get (NMConnection *connection, GHashTable *existing_secrets, const char *setting_name, const char *verb, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char **hints, NMAgentSecretsResultFunc callback, gpointer callback_data, @@ -883,8 +875,7 @@ set_secrets_not_required (NMConnection *connection, GHashTable *hash) * "secrets" property is actually a hash table of secrets. */ if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 - && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0 - && G_VALUE_HOLDS (val, DBUS_TYPE_G_MAP_OF_STRING)) { + && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0) { GHashTableIter vpn_secret_iter; const char *secret_name; @@ -904,11 +895,16 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre Request *parent = (Request *) req; NMConnection *tmp; - tmp = nm_connection_duplicate (req->connection); + tmp = nm_simple_connection_new_clone (req->connection); nm_connection_clear_secrets (tmp); if (include_system_secrets) { - if (req->existing_secrets) - (void) nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL); + if (req->existing_secrets) { + GVariant *secrets_dict; + + secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets); + (void) nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } } else { /* Update secret flags in the temporary connection to indicate that * the system secrets we're not sending to the agent aren't required, @@ -1001,7 +997,8 @@ check_system_secrets_cb (NMSetting *setting, *has_system = TRUE; } } else { - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) + g_return_if_reached (); if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) *has_system = TRUE; } @@ -1033,7 +1030,7 @@ get_next_cb (Request *parent) * secrets to the agent. We shouldn't leak system-owned secrets to * unprivileged users. */ - if ( (req->flags != NM_SETTINGS_GET_SECRETS_FLAG_NONE) + if ( (req->flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) && (req->existing_secrets || has_system_secrets (req->connection))) { nm_log_dbg (LOGD_AGENTS, "(%p/%s/%s) request has system secrets; checking agent %s for MODIFY", req, parent->detail, req->setting_name, agent_dbus_owner); @@ -1081,22 +1078,24 @@ get_start (gpointer user_data) if (setting_secrets && g_hash_table_size (setting_secrets)) { NMConnection *tmp; GError *error = NULL; - gboolean new_secrets = (req->flags & NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW); + gboolean new_secrets = (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); + GVariant *secrets_dict; /* The connection already had secrets; check if any more are required. * If no more are required, we're done. If secrets are still needed, * ask a secret agent for more. This allows admins to provide generic * secrets but allow additional user-specific ones as well. */ - tmp = nm_connection_duplicate (req->connection); + tmp = nm_simple_connection_new_clone (req->connection); g_assert (tmp); - if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { + secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets); + if (!nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, &error)) { req_complete_error (parent, error); g_clear_error (&error); } else { /* Do we have everything we need? */ - if ( (req->flags & NM_SETTINGS_GET_SECRETS_FLAG_ONLY_SYSTEM) + if ( (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM) || ((nm_connection_need_secrets (tmp, NULL) == NULL) && (new_secrets == FALSE))) { nm_log_dbg (LOGD_AGENTS, "(%p/%s/%s) system settings secrets sufficient", req, parent->detail, req->setting_name); @@ -1108,9 +1107,16 @@ get_start (gpointer user_data) req, parent->detail, req->setting_name); /* We don't, so ask some agents for additional secrets */ - request_next_agent (parent); + if ( req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS + && !parent->pending) { + /* The request initiated from GetSecrets() via DBus, + * don't error out if any secrets are missing. */ + req_complete_success (parent, req->existing_secrets, NULL, NULL); + } else + request_next_agent (parent); } } + g_variant_unref (secrets_dict); g_object_unref (tmp); } else { /* Couldn't get secrets from system settings, so now we ask the @@ -1168,7 +1174,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, NMAuthSubject *subject, GHashTable *existing_secrets, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char **hints, NMAgentSecretsResultFunc callback, gpointer callback_data, @@ -1191,7 +1197,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, /* NOTE: a few things in the Request handling depend on existing_secrets * being NULL if there aren't any system-owned secrets for this connection. - * This in turn depends on nm_connection_to_hash() and nm_setting_to_hash() + * This in turn depends on nm_connection_to_dbus() and nm_setting_to_hash() * both returning NULL if they didn't hash anything. */ @@ -1214,7 +1220,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, g_hash_table_insert (priv->requests, GUINT_TO_POINTER (parent->reqid), req); /* Kick off the request */ - if (!(req->flags & NM_SETTINGS_GET_SECRETS_FLAG_ONLY_SYSTEM)) + if (!(req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM)) request_add_agents (self, parent); parent->idle_id = g_idle_add (get_start, req); return parent->reqid; @@ -1442,11 +1448,13 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager, NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (manager); GHashTableIter iter; NMSecretAgent *agent; + gboolean subject_is_unix_process = nm_auth_subject_is_unix_process (subject); + gulong subject_uid = subject_is_unix_process ? nm_auth_subject_get_unix_process_uid (subject) : 0; g_hash_table_iter_init (&iter, priv->agents); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &agent)) { - if ( !nm_auth_subject_get_internal (subject) - && nm_secret_agent_get_owner_uid (agent) != nm_auth_subject_get_uid (subject)) + if ( subject_is_unix_process + && nm_secret_agent_get_owner_uid (agent) != subject_uid) continue; if (!(nm_secret_agent_get_capabilities (agent) & capability)) @@ -1507,9 +1515,8 @@ agent_permissions_changed_done (NMAuthChain *chain, } static void -authority_changed_cb (gpointer user_data) +authority_changed_cb (NMAuthManager *auth_manager, NMAgentManager *self) { - NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); GHashTableIter iter; NMSecretAgent *agent; @@ -1560,7 +1567,10 @@ nm_agent_manager_get (void) G_CALLBACK (name_owner_changed_cb), singleton); - nm_auth_changed_func_register (authority_changed_cb, singleton); + g_signal_connect (nm_auth_manager_get (), + NM_AUTH_MANAGER_SIGNAL_CHANGED, + G_CALLBACK (authority_changed_cb), + singleton); return singleton; } @@ -1585,7 +1595,9 @@ dispose (GObject *object) if (!priv->disposed) { priv->disposed = TRUE; - nm_auth_changed_func_unregister (authority_changed_cb, NM_AGENT_MANAGER (object)); + g_signal_handlers_disconnect_by_func (nm_auth_manager_get (), + G_CALLBACK (authority_changed_cb), + object); g_slist_free_full (priv->chains, (GDestroyNotify) nm_auth_chain_unref); diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 5fdd66ef..ac29df22 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -18,14 +18,14 @@ * Copyright (C) 2010 - 2011 Red Hat, Inc. */ -#ifndef NM_AGENT_MANAGER_H -#define NM_AGENT_MANAGER_H +#ifndef __NETWORKMANAGER_AGENT_MANAGER_H__ +#define __NETWORKMANAGER_AGENT_MANAGER_H__ #include #include #include -#include "nm-settings-flags.h" #include "nm-secret-agent.h" +#include "nm-types.h" #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) #define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) @@ -34,20 +34,9 @@ #define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AGENT_MANAGER)) #define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) -typedef enum { - NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, /*< nick=SenderUnknown >*/ - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ - NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, /*< nick=SessionNotFound >*/ - NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, /*< nick=InvalidIdentifier >*/ - NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, /*< nick=NotRegistered >*/ - NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, /*< nick=InternalError >*/ - NM_AGENT_MANAGER_ERROR_NO_SECRETS, /*< nick=NoSecrets >*/ - NM_AGENT_MANAGER_ERROR_USER_CANCELED /*< nick=UserCanceled >*/ -} NMAgentManagerError; - -typedef struct { +struct _NMAgentManager { GObject parent; -} NMAgentManager; +}; typedef struct { GObjectClass parent; @@ -67,7 +56,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, const char *agent_uname, gboolean agent_has_modify, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, GHashTable *secrets, GError *error, gpointer user_data, @@ -79,7 +68,7 @@ guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, NMAuthSubject *subject, GHashTable *existing_secrets, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char **hints, NMAgentSecretsResultFunc callback, gpointer callback_data, @@ -103,4 +92,4 @@ gboolean nm_agent_manager_all_agents_have_capability (NMAgentManager *manager, NMAuthSubject *subject, NMSecretAgentCapabilities capability); -#endif /* NM_AGENT_MANAGER_H */ +#endif /* __NETWORKMANAGER_AGENT_MANAGER_H__ */ diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c index 7231b57e..85b3c400 100644 --- a/src/settings/nm-inotify-helper.c +++ b/src/settings/nm-inotify-helper.c @@ -18,6 +18,8 @@ * (C) Copyright 2008 Red Hat, Inc. */ +#include "config.h" + #include #include #include diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index bf0bba12..69a5cea2 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -18,7 +18,7 @@ * Copyright (C) 2010 - 2011 Red Hat, Inc. */ -#include +#include "config.h" #include #include @@ -27,12 +27,15 @@ #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-secret-agent.h" #include "nm-dbus-manager.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-logging.h" +#include "nm-auth-subject.h" +#include "nm-simple-connection.h" +#include "NetworkManagerUtils.h" G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) @@ -105,9 +108,9 @@ nm_secret_agent_get_description (NMSecretAgent *agent) priv = NM_SECRET_AGENT_GET_PRIVATE (agent); if (!priv->description) { priv->description = g_strdup_printf ("%s/%s/%lu", - nm_auth_subject_get_dbus_sender (priv->subject), + nm_auth_subject_get_unix_process_dbus_sender (priv->subject), priv->identifier, - nm_auth_subject_get_uid (priv->subject)); + nm_auth_subject_get_unix_process_uid (priv->subject)); } return priv->description; @@ -118,7 +121,7 @@ nm_secret_agent_get_dbus_owner (NMSecretAgent *agent) { g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); - return nm_auth_subject_get_dbus_sender (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); + return nm_auth_subject_get_unix_process_dbus_sender (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); } const char * @@ -134,7 +137,7 @@ nm_secret_agent_get_owner_uid (NMSecretAgent *agent) { g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXULONG); - return nm_auth_subject_get_uid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); + return nm_auth_subject_get_unix_process_uid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); } const char * @@ -150,7 +153,7 @@ nm_secret_agent_get_pid (NMSecretAgent *agent) { g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXULONG); - return nm_auth_subject_get_pid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); + return nm_auth_subject_get_unix_process_pid (NM_SECRET_AGENT_GET_PRIVATE (agent)->subject); } NMSecretAgentCapabilities @@ -276,11 +279,12 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, const char *setting_name, const char **hints, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, NMSecretAgentCallback callback, gpointer callback_data) { NMSecretAgentPrivate *priv; + GVariant *dict; GHashTable *hash; Request *r; @@ -291,10 +295,13 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); g_return_val_if_fail (priv->proxy != NULL, NULL); - hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); - /* Mask off the private ONLY_SYSTEM flag if present */ - flags &= ~NM_SETTINGS_GET_SECRETS_FLAG_ONLY_SYSTEM; + /* Mask off the private flags if present */ + flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM; + flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS; r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, @@ -377,17 +384,20 @@ agent_save_delete_cb (DBusGProxy *proxy, static gpointer agent_new_save_delete (NMSecretAgent *self, NMConnection *connection, - NMSettingHashFlags hash_flags, + NMConnectionSerializationFlags flags, const char *method, NMSecretAgentCallback callback, gpointer callback_data) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GVariant *dict; GHashTable *hash; Request *r; const char *cpath = nm_connection_get_path (connection); - hash = nm_connection_to_hash (connection, hash_flags); + dict = nm_connection_to_dbus (connection, flags); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); r = request_new (self, cpath, NULL, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, @@ -417,7 +427,7 @@ nm_secret_agent_save_secrets (NMSecretAgent *self, /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ return agent_new_save_delete (self, connection, - NM_SETTING_HASH_FLAG_ALL, + NM_CONNECTION_SERIALIZE_ALL, "SaveSecrets", callback, callback_data); @@ -435,7 +445,7 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self, /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ return agent_new_save_delete (self, connection, - NM_SETTING_HASH_FLAG_NO_SECRETS, + NM_CONNECTION_SERIALIZE_NO_SECRETS, "DeleteSecrets", callback, callback_data); @@ -468,9 +478,10 @@ nm_secret_agent_new (DBusGMethodInvocation *context, g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); + g_return_val_if_fail (nm_auth_subject_is_unix_process (subject), NULL); g_return_val_if_fail (identifier != NULL, NULL); - pw = getpwuid (nm_auth_subject_get_uid (subject)); + pw = getpwuid (nm_auth_subject_get_unix_process_uid (subject)); g_return_val_if_fail (pw != NULL, NULL); g_return_val_if_fail (pw->pw_name[0] != '\0', NULL); username = g_strdup (pw->pw_name); @@ -483,13 +494,13 @@ nm_secret_agent_new (DBusGMethodInvocation *context, priv->capabilities = capabilities; priv->subject = g_object_ref (subject); - hash_str = g_strdup_printf ("%16lu%s", nm_auth_subject_get_uid (subject), identifier); + hash_str = g_strdup_printf ("%16lu%s", nm_auth_subject_get_unix_process_uid (subject), identifier); priv->hash = g_str_hash (hash_str); g_free (hash_str); priv->proxy = nm_dbus_manager_new_proxy (nm_dbus_manager_get (), context, - nm_auth_subject_get_dbus_sender (subject), + nm_auth_subject_get_unix_process_dbus_sender (subject), NM_DBUS_PATH_SECRET_AGENT, NM_DBUS_INTERFACE_SECRET_AGENT); g_assert (priv->proxy); diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h index 69699af1..f3f4ff89 100644 --- a/src/settings/nm-secret-agent.h +++ b/src/settings/nm-secret-agent.h @@ -18,26 +18,14 @@ * Copyright (C) 2010 - 2011 Red Hat, Inc. */ -#ifndef NM_SECRET_AGENT_H -#define NM_SECRET_AGENT_H +#ifndef __NETWORKMANAGER_SECRET_AGENT_H__ +#define __NETWORKMANAGER_SECRET_AGENT_H__ #include #include -#include -#include #include -#include "nm-dbus-manager.h" -#include "nm-settings-flags.h" -#include "nm-auth-subject.h" - -/* NOTE: ensure these capabilities match those in introspection/nm-secret-agent.xml and - * libnm-glib/nm-secret-agent.h. - */ -typedef enum { - NM_SECRET_AGENT_CAPABILITY_NONE = 0x0, - NM_SECRET_AGENT_CAPABILITY_VPN_HINTS = 0x1, -} NMSecretAgentCapabilities; +#include "nm-types.h" #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) @@ -46,9 +34,9 @@ typedef enum { #define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT)) #define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) -typedef struct { +struct _NMSecretAgent { GObject parent; -} NMSecretAgent; +}; typedef struct { GObjectClass parent; @@ -96,7 +84,7 @@ gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, NMConnection *connection, const char *setting_name, const char **hints, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, NMSecretAgentCallback callback, gpointer callback_data); @@ -113,4 +101,4 @@ gconstpointer nm_secret_agent_delete_secrets (NMSecretAgent *agent, NMSecretAgentCallback callback, gpointer callback_data); -#endif /* NM_SECRET_AGENT_H */ +#endif /* __NETWORKMANAGER_SECRET_AGENT_H__ */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index d20dbc98..529f4d8f 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -15,32 +15,29 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2013 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. */ #include "config.h" #include -#include -#include +#include #include -#include -#include -#include -#include #include "nm-settings-connection.h" #include "nm-session-monitor.h" #include "nm-dbus-manager.h" -#include "nm-settings-error.h" #include "nm-dbus-glib-types.h" #include "nm-logging.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" +#include "nm-auth-subject.h" #include "nm-agent-manager.h" #include "NetworkManagerUtils.h" #include "nm-properties-changed-signal.h" +#include "nm-core-internal.h" +#include "nm-glib-compat.h" #define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps" #define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids" @@ -66,9 +63,16 @@ static void impl_settings_connection_get_secrets (NMSettingsConnection *connecti const gchar *setting_name, DBusGMethodInvocation *context); +static void impl_settings_connection_clear_secrets (NMSettingsConnection *connection, + DBusGMethodInvocation *context); + #include "nm-settings-connection-glue.h" -G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_CONNECTION) +static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_settings_connection_connection_interface_init) + ) #define NM_SETTINGS_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SETTINGS_CONNECTION, \ @@ -78,6 +82,7 @@ enum { PROP_0 = 0, PROP_VISIBLE, PROP_UNSAVED, + PROP_FLAGS, }; enum { @@ -89,21 +94,11 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { - gboolean disposed; - NMAgentManager *agent_mgr; NMSessionMonitor *session_monitor; guint session_changed_id; - /* TRUE if the connection has not yet been saved to disk, - * or if it contains changes that have not been saved to disk. - */ - gboolean unsaved; - - /* TRUE if the connection was generated by NetworkManager and has - * not been saved or modified by the user. - */ - gboolean nm_generated; + NMSettingsConnectionFlags flags; guint updated_idle_id; @@ -146,6 +141,7 @@ typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, static void for_each_secret (NMConnection *connection, GHashTable *secrets, + gboolean remove_non_secrets, ForEachSecretFunc callback, gpointer callback_data) { @@ -169,6 +165,8 @@ for_each_secret (NMConnection *connection, * each time. */ + g_return_if_fail (callback); + /* Walk through the list of setting hashes */ g_hash_table_iter_init (&iter, secrets); while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { @@ -177,6 +175,9 @@ for_each_secret (NMConnection *connection, const char *secret_name; GValue *val; + if (g_hash_table_size (setting_hash) == 0) + continue; + /* Get the actual NMSetting from the connection so we can get secret flags * from the connection data, since flags aren't secrets. What we're * iterating here is just the secrets, not a whole connection. @@ -205,7 +206,11 @@ for_each_secret (NMConnection *connection, return; } } else { - nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL); + if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (remove_non_secrets) + g_hash_table_iter_remove (&secret_iter); + continue; + } if (callback (&secret_iter, secret_flags, callback_data) == FALSE) return; } @@ -355,7 +360,7 @@ update_system_secrets_cache (NMSettingsConnection *self) if (priv->system_secrets) g_object_unref (priv->system_secrets); - priv->system_secrets = nm_connection_duplicate (NM_CONNECTION (self)); + priv->system_secrets = nm_simple_connection_new_clone (NM_CONNECTION (self)); /* Clear out non-system-owned and not-saved secrets */ nm_connection_clear_secrets_with_flags (priv->system_secrets, @@ -371,7 +376,7 @@ update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new) if (priv->agent_secrets) g_object_unref (priv->agent_secrets); - priv->agent_secrets = nm_connection_duplicate (new ? new : NM_CONNECTION (self)); + priv->agent_secrets = nm_simple_connection_new_clone (new ? new : NM_CONNECTION (self)); /* Clear out non-system-owned secrets */ nm_connection_clear_secrets_with_flags (priv->agent_secrets, @@ -403,14 +408,17 @@ emit_updated (NMSettingsConnection *self) static void set_unsaved (NMSettingsConnection *self, gboolean now_unsaved) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - if (priv->unsaved != now_unsaved) { - priv->unsaved = now_unsaved; - if (!priv->unsaved) - priv->nm_generated = FALSE; + NMSettingsConnectionFlags flags = nm_settings_connection_get_flags (self); - g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_UNSAVED); + if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != !!now_unsaved) { + if (now_unsaved) + flags |= NM_SETTINGS_CONNECTION_FLAGS_UNSAVED; + else { + flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED); + } + nm_settings_connection_set_flags_all (self, flags); } } @@ -437,7 +445,6 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, GError **error) { NMSettingsConnectionPrivate *priv; - GHashTable *hash = NULL; gboolean success = FALSE; g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); @@ -445,8 +452,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - nm_utils_normalize_connection (new_connection, TRUE); - if (!nm_connection_verify (new_connection, error)) + if (!nm_connection_normalize (new_connection, NULL, NULL, error)) return FALSE; /* Do nothing if there's nothing to update */ @@ -461,37 +467,40 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, */ g_signal_handlers_block_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE)); - if (nm_connection_replace_settings_from_connection (NM_CONNECTION (self), - new_connection, - error)) { - priv->nm_generated = FALSE; + nm_utils_log_connection_diff (new_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, "update connection", "++ "); - /* Cache the just-updated system secrets in case something calls - * nm_connection_clear_secrets() and clears them. - */ - update_system_secrets_cache (self); - success = TRUE; + nm_connection_replace_settings_from_connection (NM_CONNECTION (self), new_connection); + nm_settings_connection_set_flags (self, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, + FALSE); - /* Add agent and always-ask secrets back; they won't necessarily be - * in the replacement connection data if it was eg reread from disk. - */ - if (priv->agent_secrets) { - hash = nm_connection_to_hash (priv->agent_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - if (hash) { - (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, NULL); - g_hash_table_destroy (hash); - } + /* Cache the just-updated system secrets in case something calls + * nm_connection_clear_secrets() and clears them. + */ + update_system_secrets_cache (self); + success = TRUE; + + /* Add agent and always-ask secrets back; they won't necessarily be + * in the replacement connection data if it was eg reread from disk. + */ + if (priv->agent_secrets) { + GVariant *dict; + + dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (dict) { + (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, dict, NULL); + g_variant_unref (dict); } + } - nm_settings_connection_recheck_visibility (self); + nm_settings_connection_recheck_visibility (self); - /* Manually emit changed signal since we disconnected the handler, but - * only update Unsaved if the caller wanted us to. - */ - changed_cb (self, GUINT_TO_POINTER (update_unsaved)); + /* Manually emit changed signal since we disconnected the handler, but + * only update Unsaved if the caller wanted us to. + */ + changed_cb (self, GUINT_TO_POINTER (update_unsaved)); - g_signal_emit (self, signals[UPDATED_BY_USER], 0); - } + g_signal_emit (self, signals[UPDATED_BY_USER], 0); g_signal_handlers_unblock_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE)); @@ -558,7 +567,7 @@ nm_settings_connection_commit_changes (NMSettingsConnection *connection, user_data); } else { GError *error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_FAILED, "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__); if (callback) callback (connection, error, user_data); @@ -579,7 +588,7 @@ nm_settings_connection_delete (NMSettingsConnection *connection, user_data); } else { GError *error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_FAILED, "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); if (callback) callback (connection, error, user_data); @@ -635,7 +644,7 @@ do_delete (NMSettingsConnection *connection, set_visible (connection, FALSE); /* Tell agents to remove secrets for this connection */ - for_agents = nm_connection_duplicate (NM_CONNECTION (connection)); + for_agents = nm_simple_connection_new_clone (NM_CONNECTION (connection)); nm_connection_clear_secrets (for_agents); nm_agent_manager_delete_secrets (priv->agent_mgr, for_agents); g_object_unref (for_agents); @@ -714,7 +723,7 @@ agent_secrets_done_cb (NMAgentManager *manager, const char *agent_username, gboolean agent_has_modify, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, GHashTable *secrets, GError *error, gpointer user_data, @@ -726,7 +735,7 @@ agent_secrets_done_cb (NMAgentManager *manager, NMSettingsConnectionSecretsFunc callback = other_data2; gpointer callback_data = other_data3; GError *local = NULL; - GHashTable *hash; + GVariant *dict; gboolean agent_had_system = FALSE; if (error) { @@ -742,7 +751,7 @@ agent_secrets_done_cb (NMAgentManager *manager, } if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { - local = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + local = g_error_new (NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); callback (self, call_id, NULL, setting_name, local, callback_data); @@ -764,9 +773,9 @@ agent_secrets_done_cb (NMAgentManager *manager, * save those system-owned secrets. If not, discard them and use the * existing secrets, or fail the connection. */ - for_each_secret (NM_CONNECTION (self), secrets, has_system_owned_secrets, &agent_had_system); + for_each_secret (NM_CONNECTION (self), secrets, TRUE, has_system_owned_secrets, &agent_had_system); if (agent_had_system) { - if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE) { + if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { /* No user interaction was allowed when requesting secrets; the * agent is being bad. Remove system-owned secrets. */ @@ -776,7 +785,7 @@ agent_secrets_done_cb (NMAgentManager *manager, call_id, agent_dbus_owner); - for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); + for_each_secret (NM_CONNECTION (self), secrets, FALSE, clear_nonagent_secrets, NULL); } else if (agent_has_modify == FALSE) { /* Agent didn't successfully authenticate; clear system-owned secrets * from the secrets the agent returned. @@ -786,7 +795,7 @@ agent_secrets_done_cb (NMAgentManager *manager, setting_name, call_id); - for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); + for_each_secret (NM_CONNECTION (self), secrets, FALSE, clear_nonagent_secrets, NULL); } } } else { @@ -804,19 +813,22 @@ agent_secrets_done_cb (NMAgentManager *manager, /* If no user interaction was allowed, make sure that no "unsaved" secrets * came back. Unsaved secrets by definition require user interaction. */ - if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE) - for_each_secret (NM_CONNECTION (self), secrets, clear_unsaved_secrets, NULL); + if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) + for_each_secret (NM_CONNECTION (self), secrets, TRUE, clear_unsaved_secrets, NULL); /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); - hash = nm_connection_to_hash (priv->system_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) { + GVariant *secrets_dict; + /* Update the connection with the agent's secrets; by this point if any * system-owned secrets exist in 'secrets' the agent that provided them * will have been authenticated, so those secrets can replace the existing * system secrets. */ - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + secrets_dict = nm_utils_connection_hash_to_dict (secrets); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets_dict, &local)) { /* Now that all secrets are updated, copy and cache new secrets, * then save them to backing storage. */ @@ -849,6 +861,7 @@ agent_secrets_done_cb (NMAgentManager *manager, local ? local->code : -1, (local && local->message) ? local->message : "(unknown)"); } + g_variant_unref (secrets_dict); } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", nm_connection_get_uuid (NM_CONNECTION (self)), @@ -860,8 +873,8 @@ agent_secrets_done_cb (NMAgentManager *manager, callback (self, call_id, agent_username, setting_name, local, callback_data); g_clear_error (&local); - if (hash) - g_hash_table_destroy (hash); + if (dict) + g_variant_unref (dict); } /** @@ -884,14 +897,15 @@ guint32 nm_settings_connection_get_secrets (NMSettingsConnection *self, NMAuthSubject *subject, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char **hints, NMSettingsConnectionSecretsFunc callback, gpointer callback_data, GError **error) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - GHashTable *existing_secrets; + GVariant *existing_secrets; + GHashTable *existing_secrets_hash; guint32 call_id = 0; char *joined_hints = NULL; @@ -899,7 +913,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, * will clear secrets on this object's settings. */ if (!priv->system_secrets) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "%s.%d - Internal error; secrets cache invalid.", __FILE__, __LINE__); return 0; @@ -907,17 +921,18 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, /* Make sure the request actually requests something we can return */ if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); return 0; } - existing_secrets = nm_connection_to_hash (priv->system_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + existing_secrets_hash = nm_utils_connection_dict_to_hash (existing_secrets); call_id = nm_agent_manager_get_secrets (priv->agent_mgr, NM_CONNECTION (self), subject, - existing_secrets, + existing_secrets_hash, setting_name, flags, hints, @@ -925,8 +940,10 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, self, callback, callback_data); + if (existing_secrets_hash) + g_hash_table_unref (existing_secrets_hash); if (existing_secrets) - g_hash_table_unref (existing_secrets); + g_variant_unref (existing_secrets); if (nm_logging_enabled (LOGL_DEBUG, LOGD_SETTINGS)) { if (hints) @@ -989,7 +1006,7 @@ pk_auth_cb (NMAuthChain *chain, /* If our NMSettingsConnection is already gone, do nothing */ if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, + NM_SETTINGS_ERROR_FAILED, "Error checking authorization: %s", chain_error->message ? chain_error->message : "(unknown)"); } else if (result != NM_AUTH_CALL_RESULT_YES) { @@ -1021,7 +1038,7 @@ _new_auth_subject (DBusGMethodInvocation *context, GError **error) { NMAuthSubject *subject; - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { g_set_error_literal (error, NM_SETTINGS_ERROR, @@ -1049,10 +1066,10 @@ auth_start (NMSettingsConnection *self, g_return_if_fail (NM_IS_AUTH_SUBJECT (subject)); /* Ensure the caller can view this connection */ - if (!nm_auth_uid_in_acl (NM_CONNECTION (self), - priv->session_monitor, - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (self), + priv->session_monitor, + subject, + &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); @@ -1131,14 +1148,15 @@ get_settings_auth_cb (NMSettingsConnection *self, if (error) dbus_g_method_return_error (context, error); else { - GHashTable *settings; + GVariant *settings; + GHashTable *settings_hash; NMConnection *dupl_con; NMSettingConnection *s_con; NMSettingWireless *s_wifi; guint64 timestamp = 0; - GSList *bssid_list; + char **bssids; - dupl_con = nm_connection_duplicate (NM_CONNECTION (self)); + dupl_con = nm_simple_connection_new_clone (NM_CONNECTION (self)); g_assert (dupl_con); /* Timestamp is not updated in connection's 'timestamp' property, @@ -1157,33 +1175,22 @@ get_settings_auth_cb (NMSettingsConnection *self, * from the same reason as timestamp. Thus we put it here to GetSettings() * return settings too. */ - bssid_list = nm_settings_connection_get_seen_bssids (self); + bssids = nm_settings_connection_get_seen_bssids (self); s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (dupl_con)); - if (bssid_list && s_wifi) { - g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssid_list, NULL); - g_slist_free_full (bssid_list, g_free); - } - - /* 802-11-wireless.security property is deprecated. But we set it here so that - * we don't disturb old clients that might expect it being properly set for - * secured Wi-Fi connections. - */ - if (nm_connection_get_setting_wireless_security (NM_CONNECTION (dupl_con))) { - s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (dupl_con)); - g_assert (s_wifi); - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NULL); - } + if (bssids && bssids[0] && s_wifi) + g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); + g_free (bssids); /* Secrets should *never* be returned by the GetSettings method, they * get returned by the GetSecrets method which can be better * protected against leakage of secrets to unprivileged callers. */ - settings = nm_connection_to_hash (NM_CONNECTION (dupl_con), NM_SETTING_HASH_FLAG_NO_SECRETS); + settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS); g_assert (settings); - dbus_g_method_return (context, settings); - g_hash_table_destroy (settings); + settings_hash = nm_utils_connection_dict_to_hash (settings); + dbus_g_method_return (context, settings_hash); + g_hash_table_destroy (settings_hash); + g_variant_unref (settings); g_object_unref (dupl_con); } } @@ -1213,6 +1220,60 @@ typedef struct { gboolean save_to_disk; } UpdateInfo; +static void +has_some_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + GParamSpec *pspec; + + if (NM_IS_SETTING_VPN (setting)) { + if (nm_setting_vpn_get_num_secrets (NM_SETTING_VPN(setting))) + *((gboolean *) user_data) = TRUE; + return; + } + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), key); + if (pspec) { + if ( (flags & NM_SETTING_PARAM_SECRET) + && !g_param_value_defaults (pspec, (GValue *)value)) + *((gboolean *) user_data) = TRUE; + } +} + +static gboolean +any_secrets_present (NMConnection *connection) +{ + gboolean has_secrets = FALSE; + + nm_connection_for_each_setting_value (connection, has_some_secrets_cb, &has_secrets); + return has_secrets; +} + +static void +cached_secrets_to_connection (NMSettingsConnection *self, NMConnection *connection) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GVariant *secrets_dict; + + if (priv->agent_secrets) { + secrets_dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (secrets_dict) { + (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } + } + if (priv->system_secrets) { + secrets_dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (secrets_dict) { + (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } + } +} + static void update_complete (NMSettingsConnection *self, UpdateInfo *info, @@ -1243,7 +1304,7 @@ con_update_cb (NMSettingsConnection *self, * as agent-owned secrets are the only ones we send back be saved. * Only send secrets to agents of the same UID that called update too. */ - for_agent = nm_connection_duplicate (NM_CONNECTION (self)); + for_agent = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets_with_flags (for_agent, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); @@ -1269,11 +1330,19 @@ update_auth_cb (NMSettingsConnection *self, return; } - /* Cache the new secrets from the agent, as stuff like inotify-triggered - * changes to connection's backing config files will blow them away if - * they're in the main connection. - */ - update_agent_secrets_cache (self, info->new_settings); + if (!any_secrets_present (info->new_settings)) { + /* If the new connection has no secrets, we do not want to remove all + * secrets, rather we keep all the existing ones. Do that by merging + * them in to the new connection. + */ + cached_secrets_to_connection (self, info->new_settings); + } else { + /* Cache the new secrets from the agent, as stuff like inotify-triggered + * changes to connection's backing config files will blow them away if + * they're in the main connection. + */ + update_agent_secrets_cache (self, info->new_settings); + } if (info->save_to_disk) { nm_settings_connection_replace_and_commit (self, @@ -1342,7 +1411,10 @@ impl_settings_connection_update_helper (NMSettingsConnection *self, /* Check if the settings are valid first */ if (new_settings) { - tmp = nm_connection_new_from_hash (new_settings, &error); + GVariant *new_settings_dict = nm_utils_connection_hash_to_dict (new_settings); + + tmp = nm_simple_connection_new_from_dbus (new_settings_dict, &error); + g_variant_unref (new_settings_dict); if (!tmp) { g_assert (error); goto error; @@ -1357,10 +1429,10 @@ impl_settings_connection_update_helper (NMSettingsConnection *self, * that's sending the update request. You can't make a connection * invisible to yourself. */ - if (!nm_auth_uid_in_acl (tmp ? tmp : NM_CONNECTION (self), - priv->session_monitor, - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (tmp ? tmp : NM_CONNECTION (self), + priv->session_monitor, + subject, + &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); @@ -1411,7 +1483,7 @@ impl_settings_connection_save (NMSettingsConnection *self, DBusGMethodInvocation *context) { /* Do nothing if the connection is already synced with disk */ - if (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->unsaved == TRUE) + if (nm_settings_connection_get_unsaved (self)) impl_settings_connection_update_helper (self, NULL, context, TRUE); else dbus_g_method_return (context); @@ -1497,6 +1569,7 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); DBusGMethodInvocation *context = user_data; + GVariant *dict; GHashTable *hash; priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); @@ -1509,20 +1582,24 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, * secrets from backing storage and those returned from the agent * by the time we get here. */ - hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS); - if (!hash) + dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (dict) + hash = nm_utils_connection_dict_to_hash (dict); + else hash = g_hash_table_new (NULL, NULL); dbus_g_method_return (context, hash); g_hash_table_destroy (hash); + if (dict) + g_variant_unref (dict); } } static void -dbus_secrets_auth_cb (NMSettingsConnection *self, - DBusGMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) +dbus_get_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + NMAuthSubject *subject, + GError *error, + gpointer user_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *setting_name = user_data; @@ -1533,7 +1610,8 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, call_id = nm_settings_connection_get_secrets (self, subject, setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_USER_REQUESTED, + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED + | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, NULL, dbus_get_agent_secrets_cb, context, @@ -1566,7 +1644,7 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, context, subject, get_modify_permission_basic (self), - dbus_secrets_auth_cb, + dbus_get_secrets_auth_cb, g_strdup (setting_name)); g_object_unref (subject); } else { @@ -1575,6 +1653,67 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, } } +static void +clear_secrets_cb (NMSettingsConnection *self, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + +static void +dbus_clear_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + NMAuthSubject *subject, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if (error) + dbus_g_method_return_error (context, error); + else { + /* Clear secrets in connection and caches */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + if (priv->system_secrets) + nm_connection_clear_secrets (priv->system_secrets); + if (priv->agent_secrets) + nm_connection_clear_secrets (priv->agent_secrets); + + /* Tell agents to remove secrets for this connection */ + nm_agent_manager_delete_secrets (priv->agent_mgr, NM_CONNECTION (self)); + + nm_settings_connection_commit_changes (self, clear_secrets_cb, context); + } +} + +static void +impl_settings_connection_clear_secrets (NMSettingsConnection *self, + DBusGMethodInvocation *context) +{ + NMAuthSubject *subject; + GError *error = NULL; + + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, + context, + subject, + get_modify_permission_basic (self), + dbus_clear_secrets_auth_cb, + NULL); + g_object_unref (subject); + } else { + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + /**************************************************************/ void @@ -1592,11 +1731,57 @@ nm_settings_connection_signal_remove (NMSettingsConnection *self) gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->unsaved; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_UNSAVED); } /**************************************************************/ +NMSettingsConnectionFlags +nm_settings_connection_get_flags (NMSettingsConnection *self) +{ + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + + return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; +} + +NMSettingsConnectionFlags +nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set) +{ + NMSettingsConnectionFlags new_flags; + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE); + + new_flags = NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; + if (set) + new_flags |= flags; + else + new_flags &= ~flags; + return nm_settings_connection_set_flags_all (self, new_flags); +} + +NMSettingsConnectionFlags +nm_settings_connection_set_flags_all (NMSettingsConnection *self, NMSettingsConnectionFlags flags) +{ + NMSettingsConnectionPrivate *priv; + NMSettingsConnectionFlags old_flags; + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + old_flags = priv->flags; + if (old_flags != flags) { + priv->flags = flags; + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_FLAGS); + if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED)) + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_UNSAVED); + } + return old_flags; +} + +/*************************************************************/ + /** * nm_settings_connection_get_timestamp: * @connection: the #NMSettingsConnection @@ -1714,59 +1899,34 @@ nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection g_key_file_free (timestamps_file); } -static guint -mac_hash (gconstpointer v) -{ - const guint8 *p = v; - guint32 i, h = 5381; - - for (i = 0; i < ETH_ALEN; i++) - h = (h << 5) + h + p[i]; - return h; -} - -static gboolean -mac_equal (gconstpointer a, gconstpointer b) -{ - return memcmp (a, b, ETH_ALEN) == 0; -} - -static guint8 * -mac_dup (const struct ether_addr *old) -{ - guint8 *new; - - g_return_val_if_fail (old != NULL, NULL); - - new = g_malloc0 (ETH_ALEN); - memcpy (new, old, ETH_ALEN); - return new; -} - /** * nm_settings_connection_get_seen_bssids: * @connection: the #NMSettingsConnection * * Returns current list of seen BSSIDs for the connection. * - * Returns: (transfer full) list of seen BSSIDs (in the standard hex-digits-and-colons notation). - * The caller is responsible for freeing the list. + * Returns: (transfer container) list of seen BSSIDs (in the standard hex-digits-and-colons notation). + * The caller is responsible for freeing the list, but not the content. **/ -GSList * +char ** nm_settings_connection_get_seen_bssids (NMSettingsConnection *connection) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); GHashTableIter iter; - char *bssid_str; - GSList *bssid_list = NULL; + char **bssids, *bssid; + int i; g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL); + bssids = g_new (char *, g_hash_table_size (priv->seen_bssids) + 1); + + i = 0; g_hash_table_iter_init (&iter, priv->seen_bssids); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &bssid_str)) - bssid_list = g_slist_prepend (bssid_list, g_strdup (bssid_str)); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &bssid)) + bssids[i++] = bssid; + bssids[i] = NULL; - return bssid_list; + return bssids; } /** @@ -1778,7 +1938,7 @@ nm_settings_connection_get_seen_bssids (NMSettingsConnection *connection) **/ gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *connection, - const struct ether_addr *bssid) + const char *bssid) { g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), FALSE); g_return_val_if_fail (bssid != NULL, FALSE); @@ -1796,7 +1956,7 @@ nm_settings_connection_has_seen_bssid (NMSettingsConnection *connection, **/ void nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, - const struct ether_addr *seen_bssid) + const char *seen_bssid) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); const char *connection_uuid; @@ -1814,8 +1974,8 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, return; /* Already in the list */ /* Add the new BSSID; let the hash take ownership of the allocated BSSID string */ - bssid_str = nm_utils_hwaddr_ntoa (seen_bssid, ARPHRD_ETHER); - g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str); + bssid_str = g_strdup (seen_bssid); + g_hash_table_insert (priv->seen_bssids, bssid_str, bssid_str); /* Build up a list of all the BSSIDs in string form */ n = 0; @@ -1853,19 +2013,6 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, } } -static void -add_seen_bssid_string (NMSettingsConnection *self, const char *bssid) -{ - struct ether_addr mac; - - g_return_if_fail (bssid != NULL); - if (ether_aton_r (bssid, &mac)) { - g_hash_table_insert (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->seen_bssids, - mac_dup (&mac), - g_strdup (bssid)); - } -} - /** * nm_settings_connection_read_and_fill_seen_bssids: * @connection: the #NMSettingsConnection @@ -1896,8 +2043,8 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *connecti if (tmp_strv) { g_hash_table_remove_all (priv->seen_bssids); for (i = 0; i < len; i++) - add_seen_bssid_string (connection, tmp_strv[i]); - g_strfreev (tmp_strv); + g_hash_table_insert (priv->seen_bssids, tmp_strv[i], tmp_strv[i]); + g_free (tmp_strv); } else { /* If this connection didn't have an entry in the seen-bssids database, * maybe this is the first time we've read it in, so populate the @@ -1907,8 +2054,11 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *connecti s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (connection)); if (s_wifi) { len = nm_setting_wireless_get_num_seen_bssids (s_wifi); - for (i = 0; i < len; i++) - add_seen_bssid_string (connection, nm_setting_wireless_get_seen_bssid (s_wifi, i)); + for (i = 0; i < len; i++) { + char *bssid_dup = g_strdup (nm_setting_wireless_get_seen_bssid (s_wifi, i)); + + g_hash_table_insert (priv->seen_bssids, bssid_dup, bssid_dup); + } } } } @@ -1992,30 +2142,28 @@ nm_settings_connection_can_autoconnect (NMSettingsConnection *connection) * Gets the "nm-generated" flag on @connection. * * A connection is "nm-generated" if it was generated by - * nm_device_generate_connection() and then assumed by #NMManager, and - * it has not been modified or saved by the user since then. In other - * words, an "nm-generated" connection reflects state that is entirely - * external to NetworkManager. + * nm_device_generate_connection() and has not been modified or + * saved by the user since then. */ gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->nm_generated; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED); } /** - * nm_settings_connection_set_nm_generated: + * nm_settings_connection_get_nm_generated_assumed: * @connection: an #NMSettingsConnection * - * Sets the "nm-generated" flag on @connection; see - * nm_settings_connection_get_nm_generated(). + * Gets the "nm-generated-assumed" flag on @connection. + * + * The connection is a generated connection especially + * generated for connection assumption. */ -void -nm_settings_connection_set_nm_generated (NMSettingsConnection *connection) +gboolean +nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); - - priv->nm_generated = TRUE; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED); } /**************************************************************/ @@ -2035,7 +2183,7 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->agent_mgr = nm_agent_manager_get (); - priv->seen_bssids = g_hash_table_new_full (mac_hash, mac_equal, g_free, g_free); + priv->seen_bssids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->autoconnect_retries = AUTOCONNECT_RETRIES_DEFAULT; priv->autoconnect_blocked_reason = NM_DEVICE_STATE_REASON_NONE; @@ -2051,40 +2199,42 @@ dispose (GObject *object) NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GSList *iter; - if (priv->disposed) - goto out; - priv->disposed = TRUE; - if (priv->updated_idle_id) { g_source_remove (priv->updated_idle_id); priv->updated_idle_id = 0; } - if (priv->system_secrets) - g_object_unref (priv->system_secrets); - if (priv->agent_secrets) - g_object_unref (priv->agent_secrets); + /* Disconnect handlers. + * changed_cb() has to be disconnected *before* nm_connection_clear_secrets(), + * because nm_connection_clear_secrets() emits NM_CONNECTION_CHANGED signal. + */ + g_signal_handlers_disconnect_by_func (self, G_CALLBACK (secrets_cleared_cb), NULL); + g_signal_handlers_disconnect_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE)); + + nm_connection_clear_secrets (NM_CONNECTION (self)); + g_clear_object (&priv->system_secrets); + g_clear_object (&priv->agent_secrets); /* Cancel PolicyKit requests */ - for (iter = priv->pending_auths; iter; iter = g_slist_next (iter)) - nm_auth_chain_unref ((NMAuthChain *) iter->data); - g_slist_free (priv->pending_auths); + g_slist_free_full (priv->pending_auths, (GDestroyNotify) nm_auth_chain_unref); priv->pending_auths = NULL; /* Cancel in-progress secrets requests */ for (iter = priv->reqs; iter; iter = g_slist_next (iter)) nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data)); g_slist_free (priv->reqs); + priv->reqs = NULL; - g_hash_table_destroy (priv->seen_bssids); + g_clear_pointer (&priv->seen_bssids, (GDestroyNotify) g_hash_table_destroy); set_visible (self, FALSE); - if (priv->session_changed_id) + if (priv->session_changed_id) { g_signal_handler_disconnect (priv->session_monitor, priv->session_changed_id); - g_object_unref (priv->agent_mgr); + priv->session_changed_id = 0; + } + g_clear_object (&priv->agent_mgr); -out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); } @@ -2092,14 +2242,18 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (object); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); switch (prop_id) { case PROP_VISIBLE: g_value_set_boolean (value, priv->visible); break; case PROP_UNSAVED: - g_value_set_boolean (value, priv->unsaved); + g_value_set_boolean (value, nm_settings_connection_get_unsaved (self)); + break; + case PROP_FLAGS: + g_value_set_uint (value, nm_settings_connection_get_flags (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2111,7 +2265,16 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + + switch (prop_id) { + case PROP_FLAGS: + nm_settings_connection_set_flags_all (self, g_value_get_uint (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -2133,21 +2296,26 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) /* Properties */ g_object_class_install_property (object_class, PROP_VISIBLE, - g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE, - "Visible", - "Visible", + g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_UNSAVED, - g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, - "Unsaved", - "TRUE when the connection has not yet been saved " - "to permanent storage (eg disk) or when it " - "has been changed but not yet saved.", + g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_FLAGS, + g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", + NM_SETTINGS_CONNECTION_FLAGS_NONE, + NM_SETTINGS_CONNECTION_FLAGS_ALL, + NM_SETTINGS_CONNECTION_FLAGS_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /* Signals */ @@ -2183,3 +2351,9 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_TYPE_FROM_CLASS (class), &dbus_glib_nm_settings_connection_object_info); } + +static void +nm_settings_connection_connection_interface_init (NMConnectionInterface *iface) +{ +} + diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 0c2ca849..254e927b 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -19,14 +19,14 @@ * (C) Copyright 2008 - 2013 Red Hat, Inc. */ -#ifndef NM_SETTINGS_CONNECTION_H -#define NM_SETTINGS_CONNECTION_H +#ifndef __NETWORKMANAGER_SETTINGS_CONNECTION_H__ +#define __NETWORKMANAGER_SETTINGS_CONNECTION_H__ -#include -#include "nm-settings-flags.h" -#include "nm-auth-subject.h" #include +#include +#include "nm-types.h" + G_BEGIN_DECLS #define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) @@ -48,8 +48,35 @@ G_BEGIN_DECLS /* Properties */ #define NM_SETTINGS_CONNECTION_VISIBLE "visible" #define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" +#define NM_SETTINGS_CONNECTION_FLAGS "flags" + + +/** + * NMSettingsConnectionFlags: + * @NM_SETTINGS_CONNECTION_FLAGS_NONE: no flag set + * @NM_SETTINGS_CONNECTION_FLAGS_UNSAVED: the connection is not saved to disk + * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if + * it was generated by NetworkManger. If the connection gets modified or saved + * by the user, the flag gets cleared. A nm-generated is implicitly unsaved. + * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED: A special kind of "nm-generated" + * connection that was specifically created for connection assumption. "nm-generated-assumed" + * implies "nm-generated". + * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags + * + * #NMSettingsConnection flags. + **/ +typedef enum +{ + NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00, + NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = 0x02, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED = 0x04, + + __NM_SETTINGS_CONNECTION_FLAGS_LAST, + NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1, +} NMSettingsConnectionFlags; + -typedef struct _NMSettingsConnection NMSettingsConnection; typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *connection, @@ -61,11 +88,11 @@ typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection gpointer user_data); struct _NMSettingsConnection { - NMConnection parent; + GObject parent; }; struct _NMSettingsConnectionClass { - NMConnectionClass parent; + GObjectClass parent; /* virtual methods */ void (*commit_changes) (NMSettingsConnection *connection, @@ -110,7 +137,7 @@ typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connectio guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection, NMAuthSubject *subject, const char *setting_name, - NMSettingsGetSecretsFlags flags, + NMSecretAgentGetSecretsFlags flags, const char **hints, NMSettingsConnectionSecretsFunc callback, gpointer callback_data, @@ -130,6 +157,10 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self); gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self); +NMSettingsConnectionFlags nm_settings_connection_get_flags (NMSettingsConnection *connection); +NMSettingsConnectionFlags nm_settings_connection_set_flags (NMSettingsConnection *connection, NMSettingsConnectionFlags flags, gboolean set); +NMSettingsConnectionFlags nm_settings_connection_set_flags_all (NMSettingsConnection *connection, NMSettingsConnectionFlags flags); + gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *connection, guint64 *out_timestamp); @@ -139,13 +170,13 @@ void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, void nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection); -GSList *nm_settings_connection_get_seen_bssids (NMSettingsConnection *connection); +char **nm_settings_connection_get_seen_bssids (NMSettingsConnection *connection); gboolean nm_settings_connection_has_seen_bssid (NMSettingsConnection *connection, - const struct ether_addr *bssid); + const char *bssid); void nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, - const struct ether_addr *seen_bssid); + const char *seen_bssid); void nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *connection); @@ -162,9 +193,9 @@ void nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connection); -void nm_settings_connection_set_nm_generated (NMSettingsConnection *connection); gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection); +gboolean nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection); G_END_DECLS -#endif /* NM_SETTINGS_CONNECTION_H */ +#endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c deleted file mode 100644 index fd4eca36..00000000 --- a/src/settings/nm-settings-error.c +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2011 Red Hat, Inc. - */ - -#include "nm-settings-error.h" - -GQuark -nm_settings_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm-settings-error"); - - return ret; -} diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h deleted file mode 100644 index a2b4cd46..00000000 --- a/src/settings/nm-settings-error.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2011 Red Hat, Inc. - */ - -#ifndef NM_SETTINGS_ERROR_H -#define NM_SETTINGS_ERROR_H - -#include -#include - -typedef enum { - NM_SETTINGS_ERROR_GENERAL = 0, /*< nick=GeneralError >*/ - NM_SETTINGS_ERROR_INVALID_CONNECTION, /*< nick=InvalidConnection >*/ - NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, /*< nick=ReadOnlyConnection >*/ - NM_SETTINGS_ERROR_INTERNAL_ERROR, /*< nick=InternalError >*/ - NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, /*< nick=SecretsUnavailable >*/ - NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, /*< nick=SecretsRequestCanceled >*/ - NM_SETTINGS_ERROR_PERMISSION_DENIED, /*< nick=PermissionDenied >*/ - NM_SETTINGS_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ - NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, /*< nick=AddNotSupported >*/ - NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, /*< nick=UpdateNotSupported >*/ - NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, /*< nick=DeleteNotSupported >*/ - NM_SETTINGS_ERROR_ADD_FAILED, /*< nick=AddFailed >*/ - NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, /*< nick=SaveHostnameNotSupported >*/ - NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, /*< nick=SaveHostnameFailed >*/ - NM_SETTINGS_ERROR_HOSTNAME_INVALID, /*< nick=HostnameInvalid >*/ - NM_SETTINGS_ERROR_UUID_EXISTS, /*< nick=UuidExists >*/ -} NMSettingsError; - -#define NM_SETTINGS_ERROR (nm_settings_error_quark ()) -GQuark nm_settings_error_quark (void); - -#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) -GType nm_settings_error_get_type (void); - -#endif /* NM_SETTINGS_ERROR_H */ diff --git a/src/settings/nm-settings-utils.c b/src/settings/nm-settings-utils.c deleted file mode 100644 index d0e21fbd..00000000 --- a/src/settings/nm-settings-utils.c +++ /dev/null @@ -1,66 +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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2011 Red Hat, Inc. - */ - -#include -#include -#include - -#include -#include "nm-settings-utils.h" - -char * -nm_settings_utils_get_default_wired_name (GHashTable *connections) -{ - GHashTableIter iter; - NMConnection *connection = NULL; - GSList *names = NULL, *niter; - char *cname = NULL; - int i = 0; - - /* Build up a list of all existing connection names for dupe checking */ - g_hash_table_iter_init (&iter, connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { - const char *id; - - id = nm_connection_get_id (connection); - g_assert (id); - names = g_slist_append (names, (gpointer) id); - } - - /* Find the next available unique connection name */ - while (!cname && (i++ < 10000)) { - char *temp; - gboolean found = FALSE; - - temp = g_strdup_printf (_("Wired connection %d"), i); - for (niter = names; niter; niter = g_slist_next (niter)) { - if (g_strcmp0 (niter->data, temp) == 0) { - found = TRUE; - g_free (temp); - break; - } - } - - if (found == FALSE) - cname = temp; - } - g_slist_free (names); - - return cname; -} - diff --git a/src/settings/nm-settings-utils.h b/src/settings/nm-settings-utils.h deleted file mode 100644 index f669d2b1..00000000 --- a/src/settings/nm-settings-utils.h +++ /dev/null @@ -1,26 +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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2011 Red Hat, Inc. - */ - -#ifndef NM_SETTINGS_UTILS_H -#define NM_SETTINGS_UTILS_H - -#include - -char *nm_settings_utils_get_default_wired_name (GHashTable *connections); - -#endif /* NM_SETTINGS_UTILS_H */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index e90776ab..9ed03f69 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -26,13 +26,16 @@ #include "config.h" #include +#include +#include #include #include #include #include #include -#include +#include "gsystem-local-alloc.h" +#include #include #include #include @@ -52,23 +55,31 @@ #include #include #include +#include "nm-core-internal.h" #include "nm-device-ethernet.h" #include "nm-dbus-glib-types.h" #include "nm-settings.h" #include "nm-settings-connection.h" -#include "nm-settings-error.h" +#include "nm-system-config-interface.h" #include "nm-logging.h" #include "nm-dbus-manager.h" -#include "nm-manager-auth.h" +#include "nm-auth-utils.h" +#include "nm-auth-subject.h" #include "nm-session-monitor.h" #include "plugins/keyfile/plugin.h" #include "nm-agent-manager.h" -#include "nm-settings-utils.h" #include "nm-connection-provider.h" #include "nm-config.h" #include "NetworkManagerUtils.h" +#define LOG(level, ...) \ + G_STMT_START { \ + nm_log ((level), LOGD_CORE, \ + "settings: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + /* LINKER CRACKROCK */ #define EXPORT(sym) void * __export_##sym = &sym; @@ -286,7 +297,7 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -294,10 +305,10 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - if (!nm_auth_uid_in_acl (NM_CONNECTION (connection), - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), + nm_session_monitor_get (), + subject, + &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); @@ -324,17 +335,17 @@ connection_sort (gconstpointer pa, gconstpointer pb) NMConnection *b = NM_CONNECTION (pb); NMSettingConnection *con_b; guint64 ts_a = 0, ts_b = 0; + gboolean can_ac_a, can_ac_b; con_a = nm_connection_get_setting_connection (a); g_assert (con_a); con_b = nm_connection_get_setting_connection (b); g_assert (con_b); - if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { - if (nm_setting_connection_get_autoconnect (con_a)) - return -1; - return 1; - } + can_ac_a = !!nm_setting_connection_get_autoconnect (con_a); + can_ac_b = !!nm_setting_connection_get_autoconnect (con_b); + if (can_ac_a != can_ac_b) + return can_ac_a ? -1 : 1; nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pa), &ts_a); nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pb), &ts_b); @@ -618,18 +629,24 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) for (iter = plugins; iter && *iter; iter++) { GModule *plugin; - char *full_name, *path; - const char *pname = *iter; + gs_free char *full_name = NULL; + gs_free char *path = NULL; + gs_free char *pname = NULL; GObject *obj; GObject * (*factory_func) (void); + struct stat st; + int errsv; + + pname = g_strdup (*iter); + g_strstrip (pname); - /* strip leading spaces */ - while (g_ascii_isspace (*pname)) - pname++; + if (!*pname) + continue; - /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */ - if (!strcmp (pname, "ifcfg-fedora")) - pname = "ifcfg-rh"; + if (!*pname || strchr (pname, '/')) { + LOG (LOGL_WARN, "ignore invalid plugin \"%s\"", pname); + continue; + } obj = find_plugin (list, pname); if (obj) @@ -647,22 +664,35 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); path = g_module_build_path (NMPLUGINDIR, full_name); + if (stat (path, &st) != 0) { + errsv = errno; + LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s", pname, path, strerror (errsv)); + continue; + } + if (!S_ISREG (st.st_mode)) { + LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': not a file", pname, path); + continue; + } + if (st.st_uid != 0) { + LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': file must be owned by root", pname, path); + continue; + } + if (st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { + LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': invalid file permissions", pname, path); + continue; + } + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); if (!plugin) { - g_set_error (error, 0, 0, - "Could not load plugin '%s': %s", - pname, g_module_error ()); - g_free (full_name); - g_free (path); - success = FALSE; - break; + LOG (LOGL_WARN, "Could not load plugin '%s' from file '%s': %s", + pname, full_name, g_module_error ()); + continue; } - g_free (full_name); - g_free (path); + /* errors after this point are fatal, because we loaded the shared library already. */ if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) { - g_set_error (error, 0, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not find plugin '%s' factory function.", pname); success = FALSE; @@ -671,7 +701,7 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) obj = (*factory_func) (); if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) { - g_set_error (error, 0, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Plugin '%s' returned invalid system config object.", pname); success = FALSE; @@ -781,7 +811,7 @@ secret_agent_registered (NMAgentManager *agent_mgr, static void openconnect_migrate_hack (NMConnection *connection) { - NMSettingVPN *s_vpn; + NMSettingVpn *s_vpn; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NOT_SAVED; /* Huge hack. There were some openconnect changes that needed to happen @@ -831,12 +861,9 @@ claim_connection (NMSettings *self, return; } - nm_utils_normalize_connection (NM_CONNECTION (connection), TRUE); - - if (!nm_connection_verify (NM_CONNECTION (connection), &error)) { - nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: '%s' / '%s' invalid: %d", - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); + if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { + nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: %s", + error->message); g_error_free (error); return; } @@ -874,6 +901,8 @@ claim_connection (NMSettings *self, (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), g_object_ref (connection)); + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ "); + /* Only emit the individual connection-added signal after connections * have been initially loaded. */ @@ -951,7 +980,7 @@ nm_settings_add_connection (NMSettings *self, g_clear_error (&add_error); } - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_FAILED, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "No plugin supported adding this connection"); return NULL; } @@ -997,7 +1026,7 @@ send_agent_owned_secrets (NMSettings *self, * as agent-owned secrets are the only ones we send back to be saved. * Only send secrets to agents of the same UID that called update too. */ - for_agent = nm_connection_duplicate (NM_CONNECTION (connection)); + for_agent = nm_simple_connection_new_clone (NM_CONNECTION (connection)); nm_connection_clear_secrets_with_flags (for_agent, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); @@ -1033,7 +1062,7 @@ pk_add_cb (NMAuthChain *chain, if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, + NM_SETTINGS_ERROR_FAILED, "Error checking authorization: %s", chain_error->message ? chain_error->message : "(unknown)"); } else if (result != NM_AUTH_CALL_RESULT_YES) { @@ -1137,12 +1166,12 @@ nm_settings_add_connection_dbus (NMSettings *self, /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + NM_SETTINGS_ERROR_NOT_SUPPORTED, "None of the registered plugins support add."); goto done; } - subject = nm_auth_subject_new_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -1153,10 +1182,10 @@ nm_settings_add_connection_dbus (NMSettings *self, /* Ensure the caller's username exists in the connection's permissions, * or that the permissions is empty (ie, visible by everyone). */ - if (!nm_auth_uid_in_acl (connection, - nm_session_monitor_get (), - nm_auth_subject_get_uid (subject), - &error_desc)) { + if (!nm_auth_is_subject_in_acl (connection, + nm_session_monitor_get (), + subject, + &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); @@ -1221,16 +1250,19 @@ impl_settings_add_connection_helper (NMSettings *self, DBusGMethodInvocation *context) { NMConnection *connection; + GVariant *dict; GError *error = NULL; - connection = nm_connection_new_from_hash (settings, &error); + dict = nm_utils_connection_hash_to_dict (settings); + connection = nm_simple_connection_new_from_dbus (dict, &error); + g_variant_unref (dict); if (connection) { nm_settings_add_connection_dbus (self, - connection, - save_to_disk, - context, - impl_settings_add_connection_add_cb, - NULL); + connection, + save_to_disk, + context, + impl_settings_add_connection_add_cb, + NULL); g_object_unref (connection); } else { g_assert (error); @@ -1358,7 +1390,7 @@ pk_hostname_cb (NMAuthChain *chain, /* If our NMSettingsConnection is already gone, do nothing */ if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, + NM_SETTINGS_ERROR_FAILED, "Error checking authorization: %s", chain_error->message ? chain_error->message : "(unknown)"); } else if (result != NM_AUTH_CALL_RESULT_YES) { @@ -1373,7 +1405,7 @@ pk_hostname_cb (NMAuthChain *chain, /* error will be cleared if any plugin supports saving the hostname */ error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + NM_SETTINGS_ERROR_FAILED, "Saving the hostname failed."); g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); @@ -1432,7 +1464,7 @@ impl_settings_save_hostname (NMSettings *self, /* Minimal validation of the hostname */ if (!validate_hostname (hostname)) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_HOSTNAME_INVALID, + NM_SETTINGS_ERROR_INVALID_HOSTNAME, "The hostname was too long or contained invalid characters."); goto done; } @@ -1440,7 +1472,7 @@ impl_settings_save_hostname (NMSettings *self, /* Do any of the plugins support setting the hostname? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + NM_SETTINGS_ERROR_NOT_SUPPORTED, "None of the registered plugins support setting the hostname."); goto done; } @@ -1471,13 +1503,12 @@ have_connection_for_device (NMSettings *self, NMDevice *device) gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; - const GByteArray *setting_mac; - const guint8 *hwaddr; - guint hwaddr_len = 0; + const char *setting_hwaddr; + const char *device_hwaddr; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - hwaddr = nm_device_get_hw_address (device, &hwaddr_len); + device_hwaddr = nm_device_get_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); @@ -1505,11 +1536,11 @@ have_connection_for_device (NMSettings *self, NMDevice *device) g_assert (s_wired != NULL); - setting_mac = nm_setting_wired_get_mac_address (s_wired); - if (setting_mac) { + setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); + if (setting_hwaddr) { /* A connection mac-locked to this device */ - if (hwaddr_len == setting_mac->len && - !memcmp (setting_mac->data, hwaddr, hwaddr_len)) + if ( device_hwaddr + && nm_utils_hwaddr_matches (setting_hwaddr, -1, device_hwaddr, -1)) return TRUE; } else { /* A connection that applies to any wired device */ @@ -1580,65 +1611,28 @@ default_wired_clear_tag (NMSettings *self, g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (default_wired_connection_updated_by_user_cb), self); if (add_to_no_auto_default) - nm_config_set_ethernet_no_auto_default (NM_SETTINGS_GET_PRIVATE (self)->config, NM_CONFIG_DEVICE (device)); + nm_config_set_ethernet_no_auto_default (NM_SETTINGS_GET_PRIVATE (self)->config, device); } void nm_settings_device_added (NMSettings *self, NMDevice *device) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMConnection *connection; NMSettingsConnection *added; - NMSetting *setting; GError *error = NULL; - const guint8 *hw_address; - char *defname, *uuid; - guint len = 0; - GByteArray *mac; - - if (!NM_IS_DEVICE_ETHERNET (device)) - return; /* If the device isn't managed or it already has a default wired connection, * ignore it. */ if ( !nm_device_get_managed (device) || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_CONNECTION_TAG) - || have_connection_for_device (self, device) - || !nm_config_get_ethernet_can_auto_default (priv->config, NM_CONFIG_DEVICE (device))) + || have_connection_for_device (self, device)) return; - hw_address = nm_device_get_hw_address (device, &len); - if (!hw_address) + connection = nm_device_new_default_connection (device); + if (!connection) return; - connection = nm_connection_new (); - g_assert (connection); - setting = nm_setting_connection_new (); - g_assert (setting); - nm_connection_add_setting (connection, setting); - - defname = nm_settings_utils_get_default_wired_name (priv->connections); - uuid = nm_utils_uuid_generate (); - g_object_set (setting, - NM_SETTING_CONNECTION_ID, defname, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), - NULL); - g_free (uuid); - g_free (defname); - - /* Lock the connection to the device */ - setting = nm_setting_wired_new (); - nm_connection_add_setting (connection, setting); - - mac = g_byte_array_sized_new (len); - g_byte_array_append (mac, hw_address, len); - g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_unref (mac); - /* Add the connection */ added = nm_settings_add_connection (self, connection, FALSE, &error); g_object_unref (connection); @@ -1769,13 +1763,8 @@ get_connections (NMConnectionProvider *provider) GSList *list = NULL; NMSettings *self = NM_SETTINGS (provider); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - NMSettingsConnection *connection; - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) - list = g_slist_prepend (list, connection); - list = g_slist_reverse (list); + 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); @@ -1934,35 +1923,31 @@ nm_settings_class_init (NMSettingsClass *class) g_object_class_install_property (object_class, PROP_UNMANAGED_SPECS, - g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, - "Unamanged device specs", - "Unmanaged device specs", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READABLE)); + g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_SETTINGS_HOSTNAME, - "Hostname", - "Persistent hostname", + g_param_spec_string (NM_SETTINGS_HOSTNAME, "", "", NULL, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CAN_MODIFY, - g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, - "CanModify", - "Can modify anything (hostname, connections, etc)", + g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, "", "", FALSE, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_CONNECTIONS, - g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, - "Connections", - "Connections", + g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "", DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[PROPERTIES_CHANGED] = @@ -2036,28 +2021,11 @@ nm_settings_class_init (NMSettingsClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); dbus_g_error_domain_register (NM_SETTINGS_ERROR, - NM_DBUS_IFACE_SETTINGS, + NM_DBUS_INTERFACE_SETTINGS, NM_TYPE_SETTINGS_ERROR); - - /* And register all the settings errors with D-Bus */ - dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR); - dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR); - dbus_g_error_domain_register (NM_SETTING_BLUETOOTH_ERROR, NULL, NM_TYPE_SETTING_BLUETOOTH_ERROR); - dbus_g_error_domain_register (NM_SETTING_CDMA_ERROR, NULL, NM_TYPE_SETTING_CDMA_ERROR); - dbus_g_error_domain_register (NM_SETTING_CONNECTION_ERROR, NULL, NM_TYPE_SETTING_CONNECTION_ERROR); - dbus_g_error_domain_register (NM_SETTING_GSM_ERROR, NULL, NM_TYPE_SETTING_GSM_ERROR); - dbus_g_error_domain_register (NM_SETTING_IP4_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP4_CONFIG_ERROR); - dbus_g_error_domain_register (NM_SETTING_IP6_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP6_CONFIG_ERROR); - dbus_g_error_domain_register (NM_SETTING_OLPC_MESH_ERROR, NULL, NM_TYPE_SETTING_OLPC_MESH_ERROR); - dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR); - dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR); - dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR); - dbus_g_error_domain_register (NM_SETTING_ADSL_ERROR, NULL, NM_TYPE_SETTING_ADSL_ERROR); - dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR); - dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR); - dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR); - dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR); - dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR); + dbus_g_error_domain_register (NM_CONNECTION_ERROR, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NM_TYPE_CONNECTION_ERROR); dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info); diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 67b7d0f6..520c4ec3 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -28,10 +28,7 @@ #include -#include "nm-settings-connection.h" -#include "nm-system-config-interface.h" -#include "nm-device.h" -#include "nm-secret-agent.h" +#include "nm-types.h" #define NM_TYPE_SETTINGS (nm_settings_get_type ()) #define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings)) @@ -52,9 +49,9 @@ #define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" #define NM_SETTINGS_SIGNAL_AGENT_REGISTERED "agent-registered" -typedef struct { +struct _NMSettings { GObject parent_instance; -} NMSettings; +}; typedef struct { GObjectClass parent_class; diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c index 2249efeb..637c301e 100644 --- a/src/settings/nm-system-config-interface.c +++ b/src/settings/nm-system-config-interface.c @@ -19,7 +19,10 @@ * Copyright (C) 2008 Novell, Inc. */ +#include "config.h" + #include "nm-system-config-interface.h" +#include "nm-settings-connection.h" static void interface_init (gpointer g_iface) @@ -33,38 +36,34 @@ interface_init (gpointer g_iface) /* Properties */ g_object_interface_install_property (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_NAME, - "Name", - "Plugin name", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_NAME, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_INFO, - "Info", - "Plugin information", - NULL, - G_PARAM_READABLE)); + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_INFO, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (g_iface, - g_param_spec_uint (NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, - "Capabilities", - "Plugin capabilties", - NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, - ( NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS - | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME), - NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, - G_PARAM_READABLE)); + g_param_spec_uint (NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, "", "", + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + ( NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS + | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME), + NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (g_iface, - g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, - "Hostname", - "Configured hostname", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); /* Signals */ g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index c04fae2d..144aadbf 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -19,13 +19,13 @@ * Copyright (C) 2008 Novell, Inc. */ -#ifndef NM_SYSTEM_CONFIG_INTERFACE_H -#define NM_SYSTEM_CONFIG_INTERFACE_H +#ifndef __NETWORKMANAGER_SYSTEM_CONFIG_INTERFACE_H__ +#define __NETWORKMANAGER_SYSTEM_CONFIG_INTERFACE_H__ #include #include #include -#include +#include "nm-types.h" G_BEGIN_DECLS diff --git a/src/settings/plugins/Makefile.am b/src/settings/plugins/Makefile.am index 41694e7e..568da7f6 100644 --- a/src/settings/plugins/Makefile.am +++ b/src/settings/plugins/Makefile.am @@ -2,6 +2,10 @@ SUBDIRS=keyfile example @GNOME_CODE_COVERAGE_RULES@ +if CONFIG_PLUGIN_IBFT +SUBDIRS+=ibft +endif + if CONFIG_PLUGIN_IFCFG_RH SUBDIRS+=ifcfg-rh endif diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in index 8c7c0bb8..1e9b0fdd 100644 --- a/src/settings/plugins/Makefile.in +++ b/src/settings/plugins/Makefile.in @@ -77,10 +77,11 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@CONFIG_PLUGIN_IFCFG_RH_TRUE@am__append_1 = ifcfg-rh -@CONFIG_PLUGIN_IFCFG_SUSE_TRUE@am__append_2 = ifcfg-suse -@CONFIG_PLUGIN_IFUPDOWN_TRUE@am__append_3 = ifupdown -@CONFIG_PLUGIN_IFNET_TRUE@am__append_4 = ifnet +@CONFIG_PLUGIN_IBFT_TRUE@am__append_1 = ibft +@CONFIG_PLUGIN_IFCFG_RH_TRUE@am__append_2 = ifcfg-rh +@CONFIG_PLUGIN_IFCFG_SUSE_TRUE@am__append_3 = ifcfg-suse +@CONFIG_PLUGIN_IFUPDOWN_TRUE@am__append_4 = ifupdown +@CONFIG_PLUGIN_IFNET_TRUE@am__append_5 = ifnet subdir = src/settings/plugins DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -157,7 +158,7 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = keyfile example ifcfg-rh ifcfg-suse ifupdown ifnet +DIST_SUBDIRS = keyfile example ibft ifcfg-rh ifcfg-suse ifupdown ifnet DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -193,6 +194,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -316,6 +319,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -335,6 +339,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -361,7 +366,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -441,7 +446,7 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ SUBDIRS = keyfile example $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) + $(am__append_3) $(am__append_4) $(am__append_5) all: all-recursive .SUFFIXES: diff --git a/src/settings/plugins/example/Makefile.am b/src/settings/plugins/example/Makefile.am index 8233a71f..b98f66ef 100644 --- a/src/settings/plugins/example/Makefile.am +++ b/src/settings/plugins/example/Makefile.am @@ -1,17 +1,14 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-example"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" # 'noinst' here because this is an example plugin we don't want to install @@ -27,15 +24,9 @@ libnm_settings_plugin_example_la_SOURCES = \ nm-example-connection.h \ plugin.c \ plugin.h \ - errors.c \ common.h \ reader.c \ writer.c -libnm_settings_plugin_example_la_LIBADD = \ - $(top_builddir)/src/libNetworkManager.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) - libnm_settings_plugin_example_la_LDFLAGS = -module -avoid-version diff --git a/src/settings/plugins/example/Makefile.in b/src/settings/plugins/example/Makefile.in index 26aa0a60..baa5c698 100644 --- a/src/settings/plugins/example/Makefile.in +++ b/src/settings/plugins/example/Makefile.in @@ -102,13 +102,9 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) -am__DEPENDENCIES_1 = -libnm_settings_plugin_example_la_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) +libnm_settings_plugin_example_la_LIBADD = am_libnm_settings_plugin_example_la_OBJECTS = \ - nm-example-connection.lo plugin.lo errors.lo reader.lo \ - writer.lo + nm-example-connection.lo plugin.lo reader.lo writer.lo libnm_settings_plugin_example_la_OBJECTS = \ $(am_libnm_settings_plugin_example_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -189,6 +185,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -312,6 +310,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -331,6 +330,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -357,7 +357,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -438,18 +438,15 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-example"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" @@ -465,16 +462,10 @@ libnm_settings_plugin_example_la_SOURCES = \ nm-example-connection.h \ plugin.c \ plugin.h \ - errors.c \ common.h \ reader.c \ writer.c -libnm_settings_plugin_example_la_LIBADD = \ - $(top_builddir)/src/libNetworkManager.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) - libnm_settings_plugin_example_la_LDFLAGS = -module -avoid-version all: all-am @@ -531,7 +522,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-example-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@ diff --git a/src/settings/plugins/example/common.h b/src/settings/plugins/example/common.h index ed0be9a7..cf209fe0 100644 --- a/src/settings/plugins/example/common.h +++ b/src/settings/plugins/example/common.h @@ -33,17 +33,6 @@ #define EXAMPLE_DIR NMCONFDIR "/example-plugin" -/* Boilerplate stuff for the plugin's error domain. Bits of the code that - * create new errors in the plugin's domain will create errors of - * type EXAMPLE_PLUGIN_ERROR like so: - * - * error = g_error_new_literal (EXAMPLE_PLUGIN_ERROR, - * , - * "This is a really bad error."); - */ -#define EXAMPLE_PLUGIN_ERROR (example_plugin_error_quark ()) -GQuark example_plugin_error_quark (void); - /* Prototypes for the reader/writer functions */ NMConnection *connection_from_file (const char *filename, GError **error); diff --git a/src/settings/plugins/example/errors.c b/src/settings/plugins/example/errors.c deleted file mode 100644 index 8181f8a3..00000000 --- a/src/settings/plugins/example/errors.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2012 Red Hat, Inc. - */ - -#include -#include "common.h" - -/* This is boilerplate code for defining the error domain that the plugin may - * return to NetworkManager for various operations. It just registers a - * GObject "quark" (a UUID really) for the error which allows glib to keep - * track of all the different error domains. - */ -GQuark -example_plugin_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("example-plugin-error-quark"); - - return error_quark; -} - - diff --git a/src/settings/plugins/example/nm-example-connection.c b/src/settings/plugins/example/nm-example-connection.c index e2226829..2f0b20a0 100644 --- a/src/settings/plugins/example/nm-example-connection.c +++ b/src/settings/plugins/example/nm-example-connection.c @@ -18,9 +18,11 @@ * Copyright (C) 2012 Red Hat, Inc. */ +#include "config.h" + #include #include -#include +#include #include #include @@ -89,7 +91,7 @@ nm_example_connection_new (const char *full_path, /* Make sure we have a UUID; just a sanity check */ uuid = nm_connection_get_uuid (NM_CONNECTION (object)); if (!uuid) { - g_set_error (error, EXAMPLE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Connection in file %s had no UUID", full_path); g_object_unref (object); object = NULL; @@ -165,12 +167,7 @@ nm_example_connection_init (NMExampleConnection *connection) static void finalize (GObject *object) { - NMExampleConnectionPrivate *priv = NM_EXAMPLE_CONNECTION_GET_PRIVATE (object); - - /* Zero out any secrets so we don't leave them in memory */ - nm_connection_clear_secrets (NM_CONNECTION (object)); - - g_free (priv->path); + g_free (NM_EXAMPLE_CONNECTION_GET_PRIVATE (object)->path); G_OBJECT_CLASS (nm_example_connection_parent_class)->finalize (object); } diff --git a/src/settings/plugins/example/nm-example-connection.h b/src/settings/plugins/example/nm-example-connection.h index 6d57a1ad..ddbd7ac2 100644 --- a/src/settings/plugins/example/nm-example-connection.h +++ b/src/settings/plugins/example/nm-example-connection.h @@ -18,8 +18,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#ifndef NM_EXAMPLE_CONNECTION_H -#define NM_EXAMPLE_CONNECTION_H +#ifndef __NETWORKMANAGER_EXAMPLE_CONNECTION_H__ +#define __NETWORKMANAGER_EXAMPLE_CONNECTION_H__ #include @@ -52,4 +52,4 @@ const char *nm_example_connection_get_path (NMExampleConnection *self); G_END_DECLS -#endif /* NM_EXAMPLE_CONNECTION_H */ +#endif /* __NETWORKMANAGER_EXAMPLE_CONNECTION_H__ */ diff --git a/src/settings/plugins/example/plugin.c b/src/settings/plugins/example/plugin.c index eea94946..9945e13b 100644 --- a/src/settings/plugins/example/plugin.c +++ b/src/settings/plugins/example/plugin.c @@ -18,11 +18,11 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include -#include #include #include @@ -198,11 +198,8 @@ update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, * an error here. */ if (error) { - nm_log_warn (LOGD_SETTINGS, "%s: '%s' / '%s' invalid: %d", - __func__, - error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)", - (error && error->message) ? error->message : "(none)", - error ? error->code : -1); + nm_log_warn (LOGD_SETTINGS, "%s: connection invalid: %s", + __func__, error->message); g_clear_error (&error); nm_settings_connection_signal_remove (orig); @@ -560,7 +557,7 @@ get_unmanaged_specs (NMSystemConfigInterface *config) ids = g_strsplit (str, ";", -1); for (i = 0; ids[i] != NULL; i++) { /* Verify unmanaged specification and add it to the list */ - if (!strncmp (ids[i], "mac:", 4) && nm_utils_hwaddr_valid (ids[i] + 4)) { + if (!strncmp (ids[i], "mac:", 4) && nm_utils_hwaddr_valid (ids[i] + 4, -1)) { specs = g_slist_append (specs, ids[i]); } else if (!strncmp (ids[i], "interface-name:", 15) && nm_utils_iface_valid_name (ids[i] + 15)) { specs = g_slist_append (specs, ids[i]); diff --git a/src/settings/plugins/example/reader.c b/src/settings/plugins/example/reader.c index 9a4cecaa..ee45440a 100644 --- a/src/settings/plugins/example/reader.c +++ b/src/settings/plugins/example/reader.c @@ -18,11 +18,12 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include -#include +#include #include "common.h" diff --git a/src/settings/plugins/example/writer.c b/src/settings/plugins/example/writer.c index f0a9ea21..41e5c498 100644 --- a/src/settings/plugins/example/writer.c +++ b/src/settings/plugins/example/writer.c @@ -18,7 +18,8 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include diff --git a/src/settings/plugins/ibft/Makefile.am b/src/settings/plugins/ibft/Makefile.am new file mode 100644 index 00000000..00a5d175 --- /dev/null +++ b/src/settings/plugins/ibft/Makefile.am @@ -0,0 +1,38 @@ +SUBDIRS = . tests + +@GNOME_CODE_COVERAGE_RULES@ + +pkglib_LTLIBRARIES = libnm-settings-plugin-ibft.la + +noinst_LTLIBRARIES = libibft-io.la + +libibft_io_la_SOURCES = \ + reader.c \ + reader.h + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/ \ + -I$(top_srcdir)/src/platform \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +libnm_settings_plugin_ibft_la_SOURCES = \ + plugin.c \ + plugin.h \ + nm-ibft-connection.c \ + nm-ibft-connection.h + +libnm_settings_plugin_ibft_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ibft_la_LIBADD = libibft-io.la + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/src/settings/plugins/ibft/Makefile.in b/src/settings/plugins/ibft/Makefile.in new file mode 100644 index 00000000..415961df --- /dev/null +++ b/src/settings/plugins/ibft/Makefile.in @@ -0,0 +1,956 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/settings/plugins/ibft +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) +libibft_io_la_LIBADD = +am_libibft_io_la_OBJECTS = reader.lo +libibft_io_la_OBJECTS = $(am_libibft_io_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libnm_settings_plugin_ibft_la_DEPENDENCIES = libibft-io.la +am_libnm_settings_plugin_ibft_la_OBJECTS = plugin.lo \ + nm-ibft-connection.lo +libnm_settings_plugin_ibft_la_OBJECTS = \ + $(am_libnm_settings_plugin_ibft_la_OBJECTS) +libnm_settings_plugin_ibft_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) \ + $(libnm_settings_plugin_ibft_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libibft_io_la_SOURCES) \ + $(libnm_settings_plugin_ibft_la_SOURCES) +DIST_SOURCES = $(libibft_io_la_SOURCES) \ + $(libnm_settings_plugin_ibft_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +SUBDIRS = . tests +pkglib_LTLIBRARIES = libnm-settings-plugin-ibft.la +noinst_LTLIBRARIES = libibft-io.la +libibft_io_la_SOURCES = \ + reader.c \ + reader.h + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/ \ + -I$(top_srcdir)/src/platform \ + -I$(top_srcdir)/src/settings \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DSBINDIR=\"$(sbindir)\" + +libnm_settings_plugin_ibft_la_SOURCES = \ + plugin.c \ + plugin.h \ + nm-ibft-connection.c \ + nm-ibft-connection.h + +libnm_settings_plugin_ibft_la_LDFLAGS = -module -avoid-version +libnm_settings_plugin_ibft_la_LIBADD = libibft-io.la +CLEANFILES = $(BUILT_SOURCES) +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ibft/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ibft/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libibft-io.la: $(libibft_io_la_OBJECTS) $(libibft_io_la_DEPENDENCIES) $(EXTRA_libibft_io_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libibft_io_la_OBJECTS) $(libibft_io_la_LIBADD) $(LIBS) + +libnm-settings-plugin-ibft.la: $(libnm_settings_plugin_ibft_la_OBJECTS) $(libnm_settings_plugin_ibft_la_DEPENDENCIES) $(EXTRA_libnm_settings_plugin_ibft_la_DEPENDENCIES) + $(AM_V_CCLD)$(libnm_settings_plugin_ibft_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ibft_la_OBJECTS) $(libnm_settings_plugin_ibft_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ibft-connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pkglibLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkglibLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + + +@GNOME_CODE_COVERAGE_RULES@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ibft/nm-ibft-connection.c b/src/settings/plugins/ibft/nm-ibft-connection.c new file mode 100644 index 00000000..5459a705 --- /dev/null +++ b/src/settings/plugins/ibft/nm-ibft-connection.c @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include "nm-ibft-connection.h" +#include "reader.h" + +G_DEFINE_TYPE (NMIbftConnection, nm_ibft_connection, NM_TYPE_SETTINGS_CONNECTION) + +NMIbftConnection * +nm_ibft_connection_new (const GPtrArray *block, GError **error) +{ + NMConnection *source; + GObject *object; + + source = connection_from_block (block, error); + if (!source) + return NULL; + + object = g_object_new (NM_TYPE_IBFT_CONNECTION, NULL); + /* Update settings with what was read from iscsiadm */ + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), + source, + FALSE, + error)) + g_clear_object (&object); + + return (NMIbftConnection *) object; +} + +/* GObject */ + +static void +nm_ibft_connection_init (NMIbftConnection *connection) +{ +} + +static void +nm_ibft_connection_class_init (NMIbftConnectionClass *ibft_connection_class) +{ +} + diff --git a/src/settings/plugins/ibft/nm-ibft-connection.h b/src/settings/plugins/ibft/nm-ibft-connection.h new file mode 100644 index 00000000..4ccebc3c --- /dev/null +++ b/src/settings/plugins/ibft/nm-ibft-connection.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef NM_IBFT_CONNECTION_H +#define NM_IBFT_CONNECTION_H + +G_BEGIN_DECLS + +#include + +#define NM_TYPE_IBFT_CONNECTION (nm_ibft_connection_get_type ()) +#define NM_IBFT_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IBFT_CONNECTION, NMIbftConnection)) +#define NM_IBFT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IBFT_CONNECTION, NMIbftConnectionClass)) +#define NM_IS_IBFT_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IBFT_CONNECTION)) +#define NM_IS_IBFT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_IBFT_CONNECTION)) +#define NM_IBFT_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IBFT_CONNECTION, NMIbftConnectionClass)) + +typedef struct { + NMSettingsConnection parent; +} NMIbftConnection; + +typedef struct { + NMSettingsConnectionClass parent; +} NMIbftConnectionClass; + +GType nm_ibft_connection_get_type (void); + +NMIbftConnection *nm_ibft_connection_new (const GPtrArray *block, + GError **error); + +G_END_DECLS + +#endif /* NM_IBFT_CONNECTION_H */ diff --git a/src/settings/plugins/ibft/plugin.c b/src/settings/plugins/ibft/plugin.c new file mode 100644 index 00000000..303971e0 --- /dev/null +++ b/src/settings/plugins/ibft/plugin.c @@ -0,0 +1,210 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "nm-dbus-glib-types.h" +#include "nm-system-config-interface.h" +#include "nm-logging.h" +#include "NetworkManagerUtils.h" + +#include "plugin.h" +#include "reader.h" +#include "nm-ibft-connection.h" + +static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); + +G_DEFINE_TYPE_EXTENDED (SCPluginIbft, sc_plugin_ibft, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, + system_config_interface_init)) + +#define SC_PLUGIN_IBFT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IBFT, SCPluginIbftPrivate)) + + +typedef struct { + GHashTable *connections; /* uuid::connection */ + gboolean initialized; +} SCPluginIbftPrivate; + +static void +read_connections (SCPluginIbft *self) +{ + SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self); + GSList *blocks = NULL, *iter; + GError *error = NULL; + NMIbftConnection *connection; + + if (!read_ibft_blocks ("/sbin/iscsiadm", &blocks, &error)) { + nm_log_dbg (LOGD_SETTINGS, _("ibft: failed to read iscsiadm records: %s"), error->message); + g_error_free (error); + return; + } + + for (iter = blocks; iter; iter = iter->next) { + connection = nm_ibft_connection_new (iter->data, &error); + if (connection) { + nm_log_info (LOGD_SETTINGS, _("ibft: read connection '%s'"), + nm_connection_get_id (NM_CONNECTION (connection))); + g_hash_table_insert (priv->connections, + g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), + connection); + } else { + nm_log_warn (LOGD_SETTINGS, _("ibft: failed to read iscsiadm record: %s"), error->message); + g_clear_error (&error); + } + } + + g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref); +} + +static GSList * +get_connections (NMSystemConfigInterface *config) +{ + SCPluginIbft *self = SC_PLUGIN_IBFT (config); + SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self); + GSList *list = NULL; + GHashTableIter iter; + NMIbftConnection *connection; + + if (!priv->initialized) { + read_connections (self); + priv->initialized = TRUE; + } + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) + list = g_slist_prepend (list, connection); + + return list; +} + +static void +init (NMSystemConfigInterface *config) +{ +} + +static void +sc_plugin_ibft_init (SCPluginIbft *self) +{ + SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self); + + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +} + +static void +dispose (GObject *object) +{ + SCPluginIbft *self = SC_PLUGIN_IBFT (object); + SCPluginIbftPrivate *priv = SC_PLUGIN_IBFT_GET_PRIVATE (self); + + if (priv->connections) { + g_hash_table_destroy (priv->connections); + priv->connections = NULL; + } + + G_OBJECT_CLASS (sc_plugin_ibft_parent_class)->dispose (object); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME: + g_value_set_string (value, "iBFT"); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO: + g_value_set_string (value, "(c) 2014 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."); + break; + case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static void +sc_plugin_ibft_class_init (SCPluginIbftClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (SCPluginIbftPrivate)); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME, + NM_SYSTEM_CONFIG_INTERFACE_NAME); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO, + NM_SYSTEM_CONFIG_INTERFACE_INFO); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES, + NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME, + NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); +} + +static void +system_config_interface_init (NMSystemConfigInterface *system_config_interface_class) +{ + /* interface implementation */ + system_config_interface_class->get_connections = get_connections; + system_config_interface_class->init = init; +} + +G_MODULE_EXPORT GObject * +nm_system_config_factory (void) +{ + static SCPluginIbft *singleton = NULL; + + if (!singleton) + singleton = SC_PLUGIN_IBFT (g_object_new (SC_TYPE_PLUGIN_IBFT, NULL)); + else + g_object_ref (singleton); + + return G_OBJECT (singleton); +} diff --git a/src/settings/plugins/ibft/plugin.h b/src/settings/plugins/ibft/plugin.h new file mode 100644 index 00000000..2c811359 --- /dev/null +++ b/src/settings/plugins/ibft/plugin.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include + +#define SC_TYPE_PLUGIN_IBFT (sc_plugin_ibft_get_type ()) +#define SC_PLUGIN_IBFT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IBFT, SCPluginIbft)) +#define SC_PLUGIN_IBFT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IBFT, SCPluginIbftClass)) +#define SC_IS_PLUGIN_IBFT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IBFT)) +#define SC_IS_PLUGIN_IBFT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_PLUGIN_IBFT)) +#define SC_PLUGIN_IBFT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IBFT, SCPluginIbftClass)) + +typedef struct _SCPluginIbft SCPluginIbft; +typedef struct _SCPluginIbftClass SCPluginIbftClass; + +struct _SCPluginIbft { + GObject parent; +}; + +struct _SCPluginIbftClass { + GObjectClass parent; +}; + +GType sc_plugin_ibft_get_type (void); + +#endif /* _PLUGIN_H_ */ + diff --git a/src/settings/plugins/ibft/reader.c b/src/settings/plugins/ibft/reader.c new file mode 100644 index 00000000..066a79f2 --- /dev/null +++ b/src/settings/plugins/ibft/reader.c @@ -0,0 +1,558 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nm-core-internal.h" +#include "nm-platform.h" +#include "nm-posix-signals.h" +#include "NetworkManagerUtils.h" +#include "nm-logging.h" + +#include "reader.h" + +#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) + +static void +iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED) +{ + /* We are in the child process here; set a different process group to + * ensure signal isolation between child and parent. + */ + pid_t pid = getpid (); + setpgid (pid, pid); + + /* + * We blocked signals in main(). We need to restore original signal + * mask for iscsiadm here so that it can receive signals. + */ + nm_unblock_posix_signals (NULL); +} + +/* Removes trailing whitespace and whitespace before and immediately after the '=' */ +static char * +remove_most_whitespace (const char *src) +{ + char *s_new, *s2; + const char *svalue; + + while (*src && g_ascii_isspace (*src)) + src++; + + svalue = strchr (src, '='); + if (!svalue || svalue == src) + return NULL; + + s_new = g_new (char, strlen (src) + 1); + + memcpy (s_new, src, svalue - src); + s_new[svalue - src] = '\0'; + g_strchomp (s_new); + + svalue++; + while (*svalue && g_ascii_isspace (*svalue)) + svalue++; + + s2 = strchr (s_new, '\0'); + s2[0] = '='; + strcpy (++s2, svalue); + g_strchomp (s2); + + return s_new; +} + +#define TAG_BEGIN "# BEGIN RECORD" +#define TAG_END "# END RECORD" + +/** + * read_ibft_blocks: + * @iscsiadm_path: path to iscsiadm program + * @out_blocks: on return if successful, a #GSList of #GPtrArray, or %NULL on + * failure + * @error: location for an error on failure + * + * Parses iscsiadm output and returns a #GSList of #GPtrArray in the @out_blocks + * argument on success, otherwise @out_blocks is set to %NULL. Each #GPtrArray + * in @out_blocks contains the lines from an iscsiadm interface block. + * + * Returns: %TRUE on success, %FALSE on errors + */ +gboolean +read_ibft_blocks (const char *iscsiadm_path, + GSList **out_blocks, + GError **error) +{ + const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL }; + const char *envp[1] = { NULL }; + GSList *blocks = NULL; + char *out = NULL, *err = NULL; + gint status = 0; + char **lines = NULL, **iter; + GPtrArray *block_lines = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (iscsiadm_path != NULL, FALSE); + g_return_val_if_fail (out_blocks != NULL && *out_blocks == NULL, FALSE); + + if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0, + iscsiadm_child_setup, NULL, &out, &err, &status, error)) + goto done; + + if (!WIFEXITED (status)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "iBFT: %s exited abnormally.", iscsiadm_path); + goto done; + } + + if (WEXITSTATUS (status) != 0) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "iBFT: %s exited with error %d. Message: '%s'", + iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)"); + goto done; + } + + nm_log_dbg (LOGD_SETTINGS, "iBFT records:\n%s", out); + + lines = g_strsplit_set (out, "\n\r", -1); + for (iter = lines; iter && *iter; iter++) { + if (!*iter[0]) + continue; + + if (!g_ascii_strncasecmp (*iter, TAG_BEGIN, STRLEN (TAG_BEGIN))) { + if (block_lines) { + PARSE_WARNING ("malformed iscsiadm record: missing END RECORD."); + g_ptr_array_unref (block_lines); + } + /* Start new record */ + block_lines = g_ptr_array_new_full (15, g_free); + } else if (!g_ascii_strncasecmp (*iter, TAG_END, STRLEN (TAG_END))) { + if (block_lines) { + if (block_lines->len) + blocks = g_slist_prepend (blocks, block_lines); + else + g_ptr_array_unref (block_lines); + block_lines = NULL; + } + } else if (block_lines) { + char *s = remove_most_whitespace (*iter); + + if (s) + g_ptr_array_add (block_lines, s); + else { + PARSE_WARNING ("malformed iscsiadm record: no = in '%s'.", *iter); + g_clear_pointer (&block_lines, g_ptr_array_unref); + } + } + } + + if (block_lines) { + PARSE_WARNING ("malformed iscsiadm record: missing # END RECORD."); + g_clear_pointer (&block_lines, g_ptr_array_unref); + } + success = TRUE; + +done: + if (lines) + g_strfreev (lines); + g_free (out); + if (success) + *out_blocks = blocks; + else + g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref); + return success; +} + +#define ISCSI_HWADDR_TAG "iface.hwaddress" +#define ISCSI_BOOTPROTO_TAG "iface.bootproto" +#define ISCSI_IPADDR_TAG "iface.ipaddress" +#define ISCSI_SUBNET_TAG "iface.subnet_mask" +#define ISCSI_GATEWAY_TAG "iface.gateway" +#define ISCSI_DNS1_TAG "iface.primary_dns" +#define ISCSI_DNS2_TAG "iface.secondary_dns" +#define ISCSI_VLAN_ID_TAG "iface.vlan_id" +#define ISCSI_IFACE_TAG "iface.net_ifacename" + +static const char * +match_iscsiadm_tag (const char *line, const char *tag) +{ + gsize taglen = strlen (tag); + + if (g_ascii_strncasecmp (line, tag, taglen) != 0) + return NULL; + if (line[taglen] != '=') + return NULL; + return line + taglen + 1; +} + +/** + * parse_ibft_config: + * @data: an array of iscsiadm interface block lines + * @error: return location for errors + * @...: pairs of key (const char *) : location (const char **) indicating the + * key to look for and the location to store the retrieved value in + * + * Parses an iscsiadm interface block into variables requested by the caller. + * Callers should verify the returned data is complete and valid. Returned + * strings are owned by @data and should not be used after @data is freed. + * + * Returns: %TRUE if at least , %FALSE on failure + */ +gboolean +parse_ibft_config (const GPtrArray *data, GError **error, ...) +{ + gboolean success = FALSE; + const char **out_value, *p; + va_list ap; + const char *key; + guint i; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->len > 0, FALSE); + + /* Find requested keys and populate return values */ + va_start (ap, error); + while ((key = va_arg (ap, const char *))) { + out_value = va_arg (ap, const char **); + *out_value = NULL; + for (i = 0; i < data->len; i++) { + p = match_iscsiadm_tag (g_ptr_array_index (data, i), key); + if (p) { + *out_value = p; + success = TRUE; + break; + } + } + } + va_end (ap); + + if (!success) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: failed to match at least one iscsiadm block field"); + } + return success; +} + +static gboolean +ip4_setting_add_from_block (const GPtrArray *block, + NMConnection *connection, + GError **error) +{ + NMSettingIPConfig *s_ip4 = NULL; + NMIPAddress *addr; + const char *s_method = NULL; + const char *s_ipaddr = NULL; + const char *s_gateway = NULL; + const char *s_dns1 = NULL; + const char *s_dns2 = NULL; + const char *s_netmask = NULL; + guint32 netmask = 0; + guint32 prefix; + + g_assert (block); + + if (!parse_ibft_config (block, error, + ISCSI_BOOTPROTO_TAG, &s_method, + ISCSI_IPADDR_TAG, &s_ipaddr, + ISCSI_SUBNET_TAG, &s_netmask, + ISCSI_GATEWAY_TAG, &s_gateway, + ISCSI_DNS1_TAG, &s_dns1, + ISCSI_DNS2_TAG, &s_dns2, + NULL)) + goto error; + + if (!s_method) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: missing " ISCSI_BOOTPROTO_TAG); + goto error; + } + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + + if (!g_ascii_strcasecmp (s_method, "dhcp")) { + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + goto success; + } else if (g_ascii_strcasecmp (s_method, "static") != 0) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: unknown " ISCSI_BOOTPROTO_TAG " '%s'.", + s_method); + goto error; + } + + /* Static configuration stuff */ + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + + /* IP address */ + if (!s_ipaddr || !nm_utils_ipaddr_valid (AF_INET, s_ipaddr)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid IP address '%s'.", + s_ipaddr); + goto error; + } + + /* Subnet/prefix */ + if (!s_netmask || inet_pton (AF_INET, s_netmask, &netmask) != 1) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid subnet mask '%s'.", + s_netmask); + goto error; + } + prefix = nm_utils_ip4_netmask_to_prefix (netmask); + + if (s_gateway && !nm_utils_ipaddr_valid (AF_INET, s_gateway)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid IP gateway '%s'.", + s_gateway); + goto error; + } + + if (s_dns1 && !nm_utils_ipaddr_valid (AF_INET, s_dns1)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid DNS1 address '%s'.", + s_dns1); + goto error; + } + + if (s_dns2 && !nm_utils_ipaddr_valid (AF_INET, s_dns2)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid DNS2 address '%s'.", + s_dns2); + goto error; + } + + addr = nm_ip_address_new (AF_INET, s_ipaddr, prefix, error); + if (!addr) { + g_prefix_error (error, "iBFT: malformed iscsiadm record: "); + goto 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, s_gateway, NULL); + + if (s_dns1) + nm_setting_ip_config_add_dns (s_ip4, s_dns1); + if (s_dns2) + nm_setting_ip_config_add_dns (s_ip4, s_dns2); + +success: + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + return TRUE; + +error: + g_clear_object (&s_ip4); + return FALSE; +} + +static gboolean +connection_setting_add (const GPtrArray *block, + NMConnection *connection, + const char *type, + const char *prefix, + const char *iface, + GError **error) +{ + NMSetting *s_con; + char *id, *uuid; + const char *s_hwaddr = NULL, *s_ip4addr = NULL, *s_vlanid; + + if (!parse_ibft_config (block, error, + ISCSI_VLAN_ID_TAG, &s_vlanid, + ISCSI_HWADDR_TAG, &s_hwaddr, + ISCSI_IPADDR_TAG, &s_ip4addr, + NULL)) + return FALSE; + if (!s_hwaddr) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: missing " ISCSI_HWADDR_TAG); + return FALSE; + } + + id = g_strdup_printf ("iBFT%s%s %s", + prefix ? " " : "", + prefix ? prefix : "", + iface); + + uuid = nm_utils_uuid_generate_from_strings ("ibft", + s_hwaddr, + s_vlanid ? "V" : "v", + s_vlanid ? s_vlanid : "", + s_ip4addr ? "A" : "DHCP", + s_ip4addr ? s_ip4addr : "", + NULL); + + s_con = nm_setting_connection_new (); + g_object_set (s_con, + NM_SETTING_CONNECTION_TYPE, type, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_READ_ONLY, TRUE, + NULL); + + g_free (uuid); + g_free (id); + + nm_connection_add_setting (connection, NM_SETTING (s_con)); + return TRUE; +} + +static gboolean +is_ibft_vlan_device (const GPtrArray *block) +{ + char *s_vlan_id = NULL; + + if (parse_ibft_config (block, NULL, ISCSI_VLAN_ID_TAG, &s_vlan_id, NULL)) { + g_assert (s_vlan_id); + + /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it + * means "no VLAN". + */ + if (nm_utils_ascii_str_to_int64 (s_vlan_id, 10, 1, 4095, -1) != -1) + return TRUE; + } + return FALSE; +} + +static gboolean +vlan_setting_add_from_block (const GPtrArray *block, + NMConnection *connection, + GError **error) +{ + NMSetting *s_vlan = NULL; + const char *vlan_id_str = NULL; + gint64 vlan_id = -1; + gboolean success; + + g_assert (block); + g_assert (connection); + + /* This won't fail since this function shouldn't be called unless the + * iBFT VLAN ID exists and is > 0. + */ + success = parse_ibft_config (block, NULL, ISCSI_VLAN_ID_TAG, &vlan_id_str, NULL); + g_assert (success); + g_assert (vlan_id_str); + + /* VLAN 0 is normally a valid VLAN ID, but in the iBFT case it means "no VLAN" */ + vlan_id = nm_utils_ascii_str_to_int64 (vlan_id_str, 10, 1, 4095, -1); + if (vlan_id == -1) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid VLAN_ID '%s'", vlan_id_str); + return FALSE; + } + + s_vlan = nm_setting_vlan_new (); + g_object_set (s_vlan, NM_SETTING_VLAN_ID, (guint32) vlan_id, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_vlan)); + + return TRUE; +} + +static gboolean +wired_setting_add_from_block (const GPtrArray *block, + NMConnection *connection, + GError **error) +{ + NMSetting *s_wired = NULL; + const char *hwaddr = NULL; + + g_assert (block); + g_assert (connection); + + if (!parse_ibft_config (block, NULL, ISCSI_HWADDR_TAG, &hwaddr, NULL)) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: missing " ISCSI_HWADDR_TAG); + return FALSE; + } + + if (!nm_utils_hwaddr_valid (hwaddr, ETH_ALEN)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: invalid " ISCSI_HWADDR_TAG " '%s'.", + hwaddr); + return FALSE; + } + + s_wired = nm_setting_wired_new (); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, hwaddr, NULL); + + nm_connection_add_setting (connection, s_wired); + return TRUE; +} + +NMConnection * +connection_from_block (const GPtrArray *block, GError **error) +{ + NMConnection *connection = NULL; + gboolean is_vlan = FALSE; + const char *iface = NULL; + + g_assert (block); + + if (!parse_ibft_config (block, error, ISCSI_IFACE_TAG, &iface, NULL)) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "iBFT: malformed iscsiadm record: missing " ISCSI_IFACE_TAG); + return NULL; + } + + connection = nm_simple_connection_new (); + + is_vlan = is_ibft_vlan_device (block); + if (is_vlan && !vlan_setting_add_from_block (block, connection, error)) + goto error; + + /* Always have a wired setting; for VLAN it defines the parent */ + if (!wired_setting_add_from_block (block, connection, error)) + goto error; + + if (!ip4_setting_add_from_block (block, connection, error)) + goto error; + + if (!connection_setting_add (block, + connection, + is_vlan ? NM_SETTING_VLAN_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME, + is_vlan ? "VLAN" : NULL, + iface, + error)) + goto error; + + if (!nm_connection_normalize (connection, NULL, NULL, error)) + goto error; + + return connection; + +error: + g_object_unref (connection); + return NULL; +} + diff --git a/src/settings/plugins/ibft/reader.h b/src/settings/plugins/ibft/reader.h new file mode 100644 index 00000000..0b2f22b6 --- /dev/null +++ b/src/settings/plugins/ibft/reader.h @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#ifndef __READER_H__ +#define __READER_H__ + +#include +#include + +gboolean read_ibft_blocks (const char *iscsiadm_path, + GSList **out_blocks, + GError **error); + +NMConnection *connection_from_block (const GPtrArray *block, GError **error); + +/* For testcases */ +gboolean parse_ibft_config (const GPtrArray *data, GError **error, ...) G_GNUC_NULL_TERMINATED; + +#endif /* __READER_H__ */ diff --git a/src/settings/plugins/ibft/tests/Makefile.am b/src/settings/plugins/ibft/tests/Makefile.am new file mode 100644 index 00000000..dd72220a --- /dev/null +++ b/src/settings/plugins/ibft/tests/Makefile.am @@ -0,0 +1,49 @@ +if ENABLE_TESTS + +@GNOME_CODE_COVERAGE_RULES@ + +AM_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/src/ \ + -I$(top_srcdir)/src/platform \ + -I$(top_srcdir)/src/settings \ + -I$(srcdir)/../ \ + -DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + -DTEST_IBFT_DIR=\"$(abs_srcdir)\" \ + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" + +AM_LDFLAGS = \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) \ + $(CODE_COVERAGE_LDFLAGS) + +noinst_PROGRAMS = test-ibft + +test_ibft_SOURCES = \ + test-ibft.c \ + ../reader.c + +test_ibft_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +TESTS = test-ibft + +endif + +EXTRA_DIST = \ + iscsiadm-test-dhcp \ + iscsiadm-test-static \ + iscsiadm-test-bad-ipaddr \ + iscsiadm-test-bad-gateway \ + iscsiadm-test-bad-dns1 \ + iscsiadm-test-bad-dns2 \ + iscsiadm-test-bad-entry \ + iscsiadm-test-bad-record \ + iscsiadm-test-vlan + diff --git a/src/settings/plugins/ibft/tests/Makefile.in b/src/settings/plugins/ibft/tests/Makefile.in new file mode 100644 index 00000000..e2f06169 --- /dev/null +++ b/src/settings/plugins/ibft/tests/Makefile.in @@ -0,0 +1,899 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-ibft$(EXEEXT) +@ENABLE_TESTS_TRUE@TESTS = test-ibft$(EXEEXT) +subdir = src/settings/plugins/ibft/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am__test_ibft_SOURCES_DIST = test-ibft.c ../reader.c +@ENABLE_TESTS_TRUE@am_test_ibft_OBJECTS = test-ibft.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ reader.$(OBJEXT) +test_ibft_OBJECTS = $(am_test_ibft_OBJECTS) +@ENABLE_TESTS_TRUE@test_ibft_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(test_ibft_SOURCES) +DIST_SOURCES = $(am__test_ibft_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +@ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ +@ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ +@ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_CFLAGS) \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/ \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/platform \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ +@ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ +@ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-ibft"\" \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ +@ENABLE_TESTS_TRUE@ -DTEST_IBFT_DIR=\"$(abs_srcdir)\" \ +@ENABLE_TESTS_TRUE@ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" + +@ENABLE_TESTS_TRUE@AM_LDFLAGS = \ +@ENABLE_TESTS_TRUE@ $(GLIB_LIBS) \ +@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) \ +@ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_LDFLAGS) + +@ENABLE_TESTS_TRUE@test_ibft_SOURCES = \ +@ENABLE_TESTS_TRUE@ test-ibft.c \ +@ENABLE_TESTS_TRUE@ ../reader.c + +@ENABLE_TESTS_TRUE@test_ibft_LDADD = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la + +EXTRA_DIST = \ + iscsiadm-test-dhcp \ + iscsiadm-test-static \ + iscsiadm-test-bad-ipaddr \ + iscsiadm-test-bad-gateway \ + iscsiadm-test-bad-dns1 \ + iscsiadm-test-bad-dns2 \ + iscsiadm-test-bad-entry \ + iscsiadm-test-bad-record \ + iscsiadm-test-vlan + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ibft/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/settings/plugins/ibft/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +test-ibft$(EXEEXT): $(test_ibft_OBJECTS) $(test_ibft_DEPENDENCIES) $(EXTRA_test_ibft_DEPENDENCIES) + @rm -f test-ibft$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ibft_OBJECTS) $(test_ibft_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ibft.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +reader.o: ../reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reader.o -MD -MP -MF $(DEPDIR)/reader.Tpo -c -o reader.o `test -f '../reader.c' || echo '$(srcdir)/'`../reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reader.Tpo $(DEPDIR)/reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../reader.c' object='reader.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reader.o `test -f '../reader.c' || echo '$(srcdir)/'`../reader.c + +reader.obj: ../reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reader.obj -MD -MP -MF $(DEPDIR)/reader.Tpo -c -o reader.obj `if test -f '../reader.c'; then $(CYGPATH_W) '../reader.c'; else $(CYGPATH_W) '$(srcdir)/../reader.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reader.Tpo $(DEPDIR)/reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../reader.c' object='reader.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reader.obj `if test -f '../reader.c'; then $(CYGPATH_W) '../reader.c'; else $(CYGPATH_W) '$(srcdir)/../reader.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +@ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns1 b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns1 new file mode 100755 index 00000000..54f02da6 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns1 @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10000.500.250.1 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns2 b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns2 new file mode 100755 index 00000000..ebd7a9ca --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-dns2 @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = blah.foo.bar.baz +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-entry b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-entry new file mode 100755 index 00000000..4e326048 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-entry @@ -0,0 +1,20 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-gateway b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-gateway new file mode 100755 index 00000000..5390a6c3 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-gateway @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = bb.cc.dd.ee +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-ipaddr b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-ipaddr new file mode 100755 index 00000000..b41cd1f1 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-ipaddr @@ -0,0 +1,21 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = aa.bb.cc.dd +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-bad-record b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-record new file mode 100755 index 00000000..22b34e6f --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-bad-record @@ -0,0 +1,18 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-dhcp b/src/settings/plugins/ibft/tests/iscsiadm-test-dhcp new file mode 100755 index 00000000..556b0586 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-dhcp @@ -0,0 +1,33 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f1 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth1 +node.name = iqn.1.2008-11.com.blahblah:iscsi1 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-static b/src/settings/plugins/ibft/tests/iscsiadm-test-static new file mode 100755 index 00000000..51711480 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-static @@ -0,0 +1,35 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.32.72 +iface.subnet_mask = 255.255.252.0 +iface.gateway = 192.168.35.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth0 +node.name = iqn.0.2008-11.com.blahblah:iscsi0 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +# BEGIN RECORD +iface.initiatorname = iqn.pjones6 +iface.hwaddress = 00:33:21:98:b9:f1 +iface.bootproto = DHCP +iface.gateway = 10.16.52.254 +iface.primary_dns = 10.16.255.2 +iface.secondary_dns = 10.16.255.3 +iface.vlan_id = 0 +iface.net_ifacename = eth1 +node.name = iqn.1.2008-11.com.blahblah:iscsi1 +node.conn[0].address = 10.16.52.16 +node.conn[0].port = 3260 +node.boot_lun = 00000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/iscsiadm-test-vlan b/src/settings/plugins/ibft/tests/iscsiadm-test-vlan new file mode 100755 index 00000000..59b80bd0 --- /dev/null +++ b/src/settings/plugins/ibft/tests/iscsiadm-test-vlan @@ -0,0 +1,19 @@ +#!/bin/bash + +cat << EOF +# BEGIN RECORD 6.2.0.873-21 +iface.initiatorname = iqn.2010-04.org.ipxe:d05faa97-c4be-44f6-a723-efde9aa399a0 +iface.transport_name = tcp +iface.hwaddress = 00:33:21:98:b9:f0 +iface.bootproto = STATIC +iface.ipaddress = 192.168.6.200 +iface.subnet_mask = 255.255.255.0 +iface.vlan_id = 123 +iface.net_ifacename = eth0 +node.name = iqn.2003-01.org.x:disk1 +node.conn[0].address = 192.168.6.32 +node.conn[0].port = 3260 +node.boot_lun = 01000000 +# END RECORD +EOF + diff --git a/src/settings/plugins/ibft/tests/test-ibft.c b/src/settings/plugins/ibft/tests/test-ibft.c new file mode 100644 index 00000000..2ff249af --- /dev/null +++ b/src/settings/plugins/ibft/tests/test-ibft.c @@ -0,0 +1,292 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" + +#include "reader.h" +#include "nm-logging.h" + +#include "nm-test-utils.h" + +static GPtrArray * +read_block (const char *iscsiadm_path, const char *expected_mac) +{ + GSList *blocks = NULL, *iter; + GPtrArray *block = NULL; + GError *error = NULL; + gboolean success; + + success = read_ibft_blocks (iscsiadm_path, &blocks, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (blocks); + + for (iter = blocks; iter; iter = iter->next) { + const char *s_hwaddr = NULL; + + if (!parse_ibft_config (iter->data, NULL, "iface.hwaddress", &s_hwaddr, NULL)) + continue; + g_assert (s_hwaddr); + if (nm_utils_hwaddr_matches (s_hwaddr, -1, expected_mac, -1)) { + block = g_ptr_array_ref (iter->data); + break; + } + } + g_assert (block); + + g_slist_foreach (blocks, (GFunc) g_ptr_array_unref, NULL); + return block; +} + +static void +test_read_ibft_dhcp (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + GError *error = NULL; + const char *mac_address; + const char *expected_mac_address = "00:33:21:98:b9:f1"; + GPtrArray *block; + + block = read_block (TEST_IBFT_DIR "/iscsiadm-test-dhcp", expected_mac_address); + + connection = connection_from_block (block, &error); + g_assert_no_error (error); + nmtst_assert_connection_verifies_without_normalization (connection); + + g_assert (!nm_connection_get_setting_vlan (connection)); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT eth1"); + g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); + g_assert (nm_setting_connection_get_autoconnect (s_con)); + g_assert (nm_setting_connection_get_read_only (s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + mac_address = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac_address); + g_assert (nm_utils_hwaddr_matches (mac_address, -1, expected_mac_address, -1)); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + + g_object_unref (connection); +} + +static void +test_read_ibft_static (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + GError *error = NULL; + const char *mac_address; + const char *expected_mac_address = "00:33:21:98:b9:f0"; + NMIPAddress *ip4_addr; + GPtrArray *block; + + block = read_block (TEST_IBFT_DIR "/iscsiadm-test-static", expected_mac_address); + + connection = connection_from_block (block, &error); + g_assert_no_error (error); + nmtst_assert_connection_verifies_without_normalization (connection); + + g_assert (!nm_connection_get_setting_vlan (connection)); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "iBFT eth0"); + g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, 0); + g_assert (nm_setting_connection_get_autoconnect (s_con)); + g_assert (nm_setting_connection_get_read_only (s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + mac_address = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac_address); + g_assert (nm_utils_hwaddr_matches (mac_address, -1, expected_mac_address, -1)); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "10.16.255.2"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "10.16.255.3"); + + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.32.72"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 22); + + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.35.254"); + + g_object_unref (connection); + g_ptr_array_unref (block); +} + +static void +test_read_ibft_malformed (gconstpointer user_data) +{ + const char *iscsiadm_path = user_data; + GSList *blocks = NULL; + GError *error = NULL; + gboolean success; + + g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*malformed iscsiadm record*"); + + success = read_ibft_blocks (iscsiadm_path, &blocks, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (blocks == NULL); + + g_test_assert_expected_messages (); +} + +static void +test_read_ibft_bad_address (gconstpointer user_data) +{ + const char *iscsiadm_path = user_data; + NMConnection *connection; + const char *expected_mac_address = "00:33:21:98:b9:f0"; + GPtrArray *block; + GError *error = NULL; + + g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); + + block = read_block (iscsiadm_path, expected_mac_address); + + connection = connection_from_block (block, &error); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert (strstr (error->message, "iBFT: malformed iscsiadm record: invalid")); + g_clear_error (&error); + g_assert (connection == NULL); + + g_ptr_array_unref (block); +} + +static void +test_read_ibft_vlan (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingVlan *s_vlan; + NMSettingIPConfig *s_ip4; + const char *mac_address; + const char *expected_mac_address = "00:33:21:98:b9:f0"; + NMIPAddress *ip4_addr; + GError *error = NULL; + GPtrArray *block; + + block = read_block (TEST_IBFT_DIR "/iscsiadm-test-vlan", expected_mac_address); + + connection = connection_from_block (block, &error); + g_assert_no_error (error); + nmtst_assert_connection_verifies_without_normalization (connection); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_VLAN_SETTING_NAME); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + mac_address = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac_address); + g_assert (nm_utils_hwaddr_matches (mac_address, -1, expected_mac_address, -1)); + + /* ===== VLAN SETTING ===== */ + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 123); + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, NULL); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 0); + + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.6.200"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, NULL); + + g_object_unref (connection); + g_ptr_array_ref (block); +} + +NMTST_DEFINE (); + +#define TPATH "/settings/plugins/ibft/" + +int main (int argc, char **argv) +{ + nmtst_init_assert_logging (&argc, &argv); + + g_test_add_func (TPATH "ibft/dhcp", test_read_ibft_dhcp); + g_test_add_func (TPATH "ibft/static", test_read_ibft_static); + g_test_add_func (TPATH "ibft/vlan", test_read_ibft_vlan); + g_test_add_data_func (TPATH "ibft/bad-record-read", TEST_IBFT_DIR "/iscsiadm-test-bad-record", test_read_ibft_malformed); + g_test_add_data_func (TPATH "ibft/bad-entry-read", TEST_IBFT_DIR "/iscsiadm-test-bad-entry", test_read_ibft_malformed); + g_test_add_data_func (TPATH "ibft/bad-ipaddr-read", TEST_IBFT_DIR "/iscsiadm-test-bad-ipaddr", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-gateway-read", TEST_IBFT_DIR "/iscsiadm-test-bad-gateway", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-dns1-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns1", test_read_ibft_bad_address); + g_test_add_data_func (TPATH "ibft/bad-dns2-read", TEST_IBFT_DIR "/iscsiadm-test-bad-dns2", test_read_ibft_bad_address); + + return g_test_run (); +} + diff --git a/src/settings/plugins/ifcfg-rh/Makefile.am b/src/settings/plugins/ifcfg-rh/Makefile.am index c5e458af..4989f4ba 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/Makefile.am @@ -19,27 +19,21 @@ libifcfg_rh_io_la_SOURCES = \ reader.h \ writer.c \ writer.h \ - errors.c \ common.h \ utils.c \ utils.h AM_CPPFLAGS = \ -I$(top_srcdir)/src/ \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/settings \ - -I$(top_srcdir)/src/posix-signals \ - -I$(top_srcdir)/src/config \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(NSS_CFLAGS) \ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-rh"\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ @@ -52,11 +46,7 @@ libnm_settings_plugin_ifcfg_rh_la_SOURCES = \ nm-ifcfg-connection.h libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - libifcfg-rh-io.la \ - $(GLIB_LIBS) +libnm_settings_plugin_ifcfg_rh_la_LIBADD = libifcfg-rh-io.la dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = nm-ifcfg-rh.conf diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in index 7b1a7dda..5d396273 100644 --- a/src/settings/plugins/ifcfg-rh/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/Makefile.in @@ -133,18 +133,13 @@ am__installdirs = "$(DESTDIR)$(pkglibdir)" \ "$(DESTDIR)$(dbusservicedir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) libifcfg_rh_io_la_LIBADD = -am_libifcfg_rh_io_la_OBJECTS = shvar.lo reader.lo writer.lo errors.lo \ - utils.lo +am_libifcfg_rh_io_la_OBJECTS = shvar.lo reader.lo writer.lo utils.lo libifcfg_rh_io_la_OBJECTS = $(am_libifcfg_rh_io_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am__DEPENDENCIES_1 = -libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la libifcfg-rh-io.la \ - $(am__DEPENDENCIES_1) +libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES = libifcfg-rh-io.la am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS = plugin.lo \ nm-ifcfg-connection.lo libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \ @@ -268,6 +263,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -391,6 +388,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -410,6 +408,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -436,7 +435,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -528,27 +527,21 @@ libifcfg_rh_io_la_SOURCES = \ reader.h \ writer.c \ writer.h \ - errors.c \ common.h \ utils.c \ utils.h AM_CPPFLAGS = \ -I$(top_srcdir)/src/ \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/settings \ - -I$(top_srcdir)/src/posix-signals \ - -I$(top_srcdir)/src/config \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(NSS_CFLAGS) \ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-rh"\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ @@ -561,12 +554,7 @@ libnm_settings_plugin_ifcfg_rh_la_SOURCES = \ nm-ifcfg-connection.h libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifcfg_rh_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - libifcfg-rh-io.la \ - $(GLIB_LIBS) - +libnm_settings_plugin_ifcfg_rh_la_LIBADD = libifcfg-rh-io.la dbusservicedir = $(DBUS_SYS_DIR) dbusservice_DATA = nm-ifcfg-rh.conf EXTRA_DIST = \ @@ -668,7 +656,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ifcfg-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@ diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h index d9627bdd..d78f3752 100644 --- a/src/settings/plugins/ifcfg-rh/common.h +++ b/src/settings/plugins/ifcfg-rh/common.h @@ -78,9 +78,5 @@ #define KEY_DCB_PG_STRICT "DCB_PG_STRICT" #define KEY_DCB_PG_UP2TC "DCB_PG_UP2TC" -#define IFCFG_PLUGIN_ERROR (ifcfg_plugin_error_quark ()) -GQuark ifcfg_plugin_error_quark (void); - - #endif /* __COMMON_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/errors.c b/src/settings/plugins/ifcfg-rh/errors.c deleted file mode 100644 index 25039104..00000000 --- a/src/settings/plugins/ifcfg-rh/errors.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 - 2009 Red Hat, Inc. - */ - -#include -#include "common.h" - -GQuark -ifcfg_plugin_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark"); - - return error_quark; -} - - diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 3db06f17..7596cbd5 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -18,13 +18,13 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ +#include "config.h" + #include -#include -#include #include -#include +#include #include #include #include @@ -119,7 +119,7 @@ nm_ifcfg_connection_new (NMConnection *source, else { char *keyfile = NULL, *routefile = NULL, *route6file = NULL; - tmp = connection_from_file (full_path, NULL, NULL, NULL, + tmp = connection_from_file (full_path, NULL, NULL, &unhandled_spec, &keyfile, &routefile, @@ -145,20 +145,16 @@ nm_ifcfg_connection_new (NMConnection *source, NM_IFCFG_CONNECTION_UNMANAGED_SPEC, unmanaged_spec, NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, unrecognized_spec, NULL); - if (object) { - /* Update our settings with what was read from the file */ - if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), - tmp, - update_unsaved, - error)) { - /* Set the path and start monitoring */ - if (full_path) - nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path); - } else { - g_object_unref (object); - object = NULL; - } - } + /* Update our settings with what was read from the file */ + if (nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), + tmp, + update_unsaved, + error)) { + /* Set the path and start monitoring */ + if (full_path) + nm_ifcfg_connection_set_path (NM_IFCFG_CONNECTION (object), full_path); + } else + g_clear_object (&object); g_object_unref (tmp); g_free (unhandled_spec); @@ -271,7 +267,7 @@ commit_changes (NMSettingsConnection *connection, * it if it's really changed. */ if (priv->path) { - reread = connection_from_file (priv->path, NULL, NULL, NULL, + reread = connection_from_file (priv->path, NULL, NULL, NULL, NULL, NULL, NULL, &error, NULL); g_clear_error (&error); @@ -344,17 +340,6 @@ nm_ifcfg_connection_init (NMIfcfgConnection *connection) { } -static void -finalize (GObject *object) -{ - nm_connection_clear_secrets (NM_CONNECTION (object)); - - path_watch_stop (NM_IFCFG_CONNECTION (object)); - g_free (NM_IFCFG_CONNECTION_GET_PRIVATE (object)->path); - - G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); -} - static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -393,6 +378,22 @@ get_property (GObject *object, guint prop_id, } } +static void +dispose (GObject *object) +{ + path_watch_stop (NM_IFCFG_CONNECTION (object)); + + G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + g_free (NM_IFCFG_CONNECTION_GET_PRIVATE (object)->path); + + G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object); +} + static void nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) { @@ -404,6 +405,7 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) /* Virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; + object_class->dispose = dispose; object_class->finalize = finalize; settings_class->delete = do_delete; settings_class->commit_changes = commit_changes; @@ -411,18 +413,16 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) /* Properties */ g_object_class_install_property (object_class, PROP_UNMANAGED_SPEC, - g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED_SPEC, - "Unmanaged spec", - "Unmanaged spec", - NULL, - G_PARAM_READWRITE)); + g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED_SPEC, "", "", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_UNRECOGNIZED_SPEC, - g_param_spec_string (NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, - "Unrecognized spec", - "Unrecognized spec", + g_param_spec_string (NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, "", "", NULL, - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); signals[IFCFG_CHANGED] = g_signal_new ("ifcfg-changed", diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 47422b5d..37eacaf0 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -18,12 +18,12 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ -#ifndef NM_IFCFG_CONNECTION_H -#define NM_IFCFG_CONNECTION_H +#ifndef __NETWORKMANAGER_IFCFG_CONNECTION_H__ +#define __NETWORKMANAGER_IFCFG_CONNECTION_H__ G_BEGIN_DECLS -#include +#include #include #define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) @@ -65,4 +65,4 @@ gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self, G_END_DECLS -#endif /* NM_IFCFG_CONNECTION_H */ +#endif /* __NETWORKMANAGER_IFCFG_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index 8a3f328c..2dced56b 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -21,12 +21,11 @@ * Copyright (C) 2007 - 2011 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include -#include -#include #include #include @@ -49,9 +48,9 @@ #include "nm-dbus-glib-types.h" #include "plugin.h" #include "nm-system-config-interface.h" -#include "nm-settings-error.h" #include "nm-config.h" #include "nm-logging.h" +#include "NetworkManagerUtils.h" #include "nm-ifcfg-connection.h" #include "nm-inotify-helper.h" @@ -143,7 +142,8 @@ _internal_new_connection (SCPluginIfcfg *self, if (local) g_propagate_error (error, local); else - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "(unknown)"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "(unknown)"); return NULL; } @@ -648,10 +648,10 @@ plugin_get_hostname (SCPluginIfcfg *plugin) hostname = svGetValue (network, "HOSTNAME", FALSE); ignore_localhost = svTrueValue (network, "NM_IGNORE_HOSTNAME_LOCALHOST", FALSE); if (ignore_localhost) { - /* Ignore a hostname of 'localhost' or 'localhost.localdomain' to preserve - * 'network' service behavior. + /* Ignore a default hostname ('localhost[6]' or 'localhost[6].localdomain[6]') + * to preserve 'network' service behavior. */ - if (hostname && (!strcmp (hostname, "localhost") || !strcmp (hostname, "localhost.localdomain"))) { + if (hostname && !nm_utils_is_specific_hostname (hostname)) { g_free (hostname); hostname = NULL; } @@ -669,12 +669,14 @@ plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname) char *hostname_eol; gboolean ret; #if HAVE_SELINUX - security_context_t se_ctx_prev, se_ctx = NULL; + security_context_t se_ctx_prev = NULL, se_ctx = NULL; struct stat file_stat = { .st_mode = 0 }; + mode_t st_mode = 0; /* Get default context for HOSTNAME_FILE and set it for fscreate */ - stat (HOSTNAME_FILE, &file_stat); - matchpathcon (HOSTNAME_FILE, file_stat.st_mode, &se_ctx); + if (stat (HOSTNAME_FILE, &file_stat) == 0) + st_mode = file_stat.st_mode; + matchpathcon (HOSTNAME_FILE, st_mode, &se_ctx); matchpathcon_fini (); getfscreatecon (&se_ctx_prev); setfscreatecon (se_ctx); @@ -790,7 +792,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, if (!s_con) { g_set_error (error, NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_FAILED, "unable to retrieve the connection setting"); return FALSE; } @@ -799,7 +801,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, if (!uuid) { g_set_error (error, NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_FAILED, "unable to get the UUID"); return FALSE; } @@ -808,7 +810,7 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, if (!path) { g_set_error (error, NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_FAILED, "unable to get the connection D-Bus path"); return FALSE; } diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 7a616707..145a0a39 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -15,10 +15,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2013 Red Hat, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include @@ -29,13 +30,11 @@ #include #include #include -#include -#include #include #include #include -#include +#include #include #include #include @@ -50,7 +49,7 @@ #include #include #include -#include +#include "nm-core-internal.h" #include #include "nm-platform.h" @@ -149,7 +148,7 @@ make_connection_setting (const char *file, uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); } g_object_set (s_con, @@ -170,8 +169,14 @@ make_connection_setting (const char *file, } /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */ - g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, + g_object_set (s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, svTrueValue (ifcfg, "ONBOOT", TRUE), + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, + (gint) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT), NULL); value = svGetValue (ifcfg, "USERS", FALSE); @@ -246,292 +251,14 @@ make_connection_setting (const char *file, return NM_SETTING (s_con); } -static gboolean -read_mac_address (shvarFile *ifcfg, const char *key, int type, - GByteArray **array, GError **error) -{ - char *value = NULL; - - g_return_val_if_fail (ifcfg != NULL, FALSE); - g_return_val_if_fail (array != NULL, FALSE); - g_return_val_if_fail (*array == NULL, FALSE); - if (error) - g_return_val_if_fail (*error == NULL, FALSE); - - value = svGetValue (ifcfg, key, FALSE); - if (!value || !strlen (value)) { - g_free (value); - return TRUE; - } - - *array = nm_utils_hwaddr_atoba (value, type); - if (!*array) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "%s: the MAC address '%s' was invalid.", key, value); - g_free (value); - return FALSE; - } - - g_free (value); - return TRUE; -} - -static void -iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED) -{ - /* We are in the child process here; set a different process group to - * ensure signal isolation between child and parent. - */ - pid_t pid = getpid (); - setpgid (pid, pid); - - /* - * We blocked signals in main(). We need to restore original signal - * mask for iscsiadm here so that it can receive signals. - */ - nm_unblock_posix_signals (NULL); -} - -static char * -match_iscsiadm_tag (const char *line, const char *tag, gboolean *skip) -{ - char *p; - - if (g_ascii_strncasecmp (line, tag, strlen (tag))) - return NULL; - - p = strchr (line, '='); - if (!p) { - PARSE_WARNING ("malformed iscsiadm record: no = in '%s'.", line); - *skip = TRUE; - return NULL; - } - - p++; /* advance past = */ - return g_strstrip (p); -} - -#define ISCSI_HWADDR_TAG "iface.hwaddress" -#define ISCSI_BOOTPROTO_TAG "iface.bootproto" -#define ISCSI_IPADDR_TAG "iface.ipaddress" -#define ISCSI_SUBNET_TAG "iface.subnet_mask" -#define ISCSI_GATEWAY_TAG "iface.gateway" -#define ISCSI_DNS1_TAG "iface.primary_dns" -#define ISCSI_DNS2_TAG "iface.secondary_dns" - -static gboolean -fill_ip4_setting_from_ibft (shvarFile *ifcfg, - NMSettingIP4Config *s_ip4, - const char *iscsiadm_path, - GError **error) -{ - const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL }; - const char *envp[1] = { NULL }; - gboolean success = FALSE, in_record = FALSE, hwaddr_matched = FALSE, skip = FALSE; - char *out = NULL, *err = NULL; - gint status = 0; - GByteArray *ifcfg_mac = NULL; - char **lines = NULL, **iter; - const char *method = NULL; - guint32 ipaddr; - guint32 gateway; - guint32 dns1; - guint32 dns2; - guint32 prefix = 0; - - g_return_val_if_fail (s_ip4 != NULL, FALSE); - g_return_val_if_fail (iscsiadm_path != NULL, FALSE); - - if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0, - iscsiadm_child_setup, NULL, &out, &err, &status, error)) - return FALSE; - - if (!WIFEXITED (status)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "%s exited abnormally.", iscsiadm_path); - goto done; - } - - if (WEXITSTATUS (status) != 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "%s exited with error %d. Message: '%s'", - iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)"); - goto done; - } - - if (!read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &ifcfg_mac, error)) - goto done; - /* Ensure we got a MAC */ - if (!ifcfg_mac) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing device MAC address (no HWADDR tag present)."); - goto done; - } - - memset (&ipaddr, 0, sizeof (ipaddr)); - memset (&gateway, 0, sizeof (gateway)); - memset (&dns1, 0, sizeof (dns1)); - memset (&dns2, 0, sizeof (dns2)); - - /* Success, lets parse the output */ - lines = g_strsplit_set (out, "\n\r", -1); - for (iter = lines; iter && *iter; iter++) { - char *p; - - if (!g_ascii_strcasecmp (*iter, "# BEGIN RECORD")) { - if (in_record) { - PARSE_WARNING ("malformed iscsiadm record: already parsing record."); - skip = TRUE; - } - } else if (!g_ascii_strcasecmp (*iter, "# END RECORD")) { - if (!skip && hwaddr_matched) { - /* Record is good; fill IP4 config with its info */ - if (!method) { - PARSE_WARNING ("malformed iscsiadm record: missing BOOTPROTO."); - goto done; - } - - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL); - - if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - NMIP4Address *addr; - - if (!ipaddr || !prefix) { - PARSE_WARNING ("malformed iscsiadm record: BOOTPROTO=static " - "but missing IP address or prefix."); - goto done; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ipaddr); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gateway); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); - - if (dns1) - nm_setting_ip4_config_add_dns (s_ip4, dns1); - if (dns2) - nm_setting_ip4_config_add_dns (s_ip4, dns2); - - // FIXME: DNS search domains? - } - success = TRUE; - goto done; - } - skip = FALSE; - hwaddr_matched = FALSE; - memset (&ipaddr, 0, sizeof (ipaddr)); - memset (&gateway, 0, sizeof (gateway)); - memset (&dns1, 0, sizeof (dns1)); - memset (&dns2, 0, sizeof (dns2)); - prefix = 0; - method = NULL; - } - - if (skip) - continue; - - /* HWADDR */ - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_HWADDR_TAG, &skip))) { - struct ether_addr *ibft_mac; - - ibft_mac = ether_aton (p); - if (!ibft_mac) { - PARSE_WARNING ("malformed iscsiadm record: invalid hwaddress."); - skip = TRUE; - continue; - } - - if (memcmp (ifcfg_mac->data, (guint8 *) ibft_mac->ether_addr_octet, ETH_ALEN)) { - /* This record isn't for the current device, ignore it */ - skip = TRUE; - continue; - } - - /* Success, this record is for this device */ - hwaddr_matched = TRUE; - } - - /* BOOTPROTO */ - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_BOOTPROTO_TAG, &skip))) { - if (!g_ascii_strcasecmp (p, "dhcp")) - method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; - else if (!g_ascii_strcasecmp (p, "static")) - method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - else { - PARSE_WARNING ("malformed iscsiadm record: unknown BOOTPROTO '%s'.", p); - skip = TRUE; - continue; - } - } - - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_IPADDR_TAG, &skip))) { - if (inet_pton (AF_INET, p, &ipaddr) < 1) { - PARSE_WARNING ("malformed iscsiadm record: invalid IP address '%s'.", p); - skip = TRUE; - continue; - } - } - - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_SUBNET_TAG, &skip))) { - guint32 mask; - - if (inet_pton (AF_INET, p, &mask) < 1) { - PARSE_WARNING ("malformed iscsiadm record: invalid subnet mask '%s'.", p); - skip = TRUE; - continue; - } - - prefix = nm_utils_ip4_netmask_to_prefix (mask); - } - - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_GATEWAY_TAG, &skip))) { - if (inet_pton (AF_INET, p, &gateway) < 1) { - PARSE_WARNING ("malformed iscsiadm record: invalid IP gateway '%s'.", p); - skip = TRUE; - continue; - } - } - - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS1_TAG, &skip))) { - if (inet_pton (AF_INET, p, &dns1) < 1) { - PARSE_WARNING ("malformed iscsiadm record: invalid DNS1 address '%s'.", p); - skip = TRUE; - continue; - } - } - - if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS2_TAG, &skip))) { - if (inet_pton (AF_INET, p, &dns2) < 1) { - PARSE_WARNING ("malformed iscsiadm record: invalid DNS2 address '%s'.", p); - skip = TRUE; - continue; - } - } - } - - success = TRUE; - -done: - if (ifcfg_mac) - g_byte_array_free (ifcfg_mac, TRUE); - g_strfreev (lines); - g_free (out); - g_free (err); - return success; -} - /* Returns TRUE on missing address or valid address */ static gboolean read_ip4_address (shvarFile *ifcfg, const char *tag, - guint32 *out_addr, + char **out_addr, GError **error) { char *value = NULL; - guint32 ip4_addr; - gboolean success = FALSE; g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (tag != NULL, FALSE); @@ -539,45 +266,21 @@ read_ip4_address (shvarFile *ifcfg, if (error) g_return_val_if_fail (*error == NULL, FALSE); - *out_addr = 0; + *out_addr = NULL; value = svGetValue (ifcfg, tag, FALSE); if (!value) return TRUE; - if (inet_pton (AF_INET, value, &ip4_addr) > 0) { - *out_addr = ip4_addr; - success = TRUE; + if (nm_utils_ipaddr_valid (AF_INET, value)) { + *out_addr = value; + return TRUE; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid %s IP4 address '%s'", tag, value); - } - g_free (value); - return success; -} - -/* Returns TRUE on valid address, including unspecified (::) */ -static gboolean -parse_ip6_address (const char *value, - struct in6_addr *out_addr, - GError **error) -{ - struct in6_addr ip6_addr; - - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (out_addr != NULL, FALSE); - if (error) - g_return_val_if_fail (*error == NULL, FALSE); - - *out_addr = in6addr_any; - if (inet_pton (AF_INET6, value, &ip6_addr) <= 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP6 address '%s'", value); + g_free (value); return FALSE; } - - *out_addr = ip6_addr; - return TRUE; } static char * @@ -629,19 +332,23 @@ static gboolean read_full_ip4_address (shvarFile *ifcfg, const char *network_file, gint32 which, - NMIP4Address *addr, + NMIPAddress *base_addr, + NMIPAddress **out_address, + char **out_gateway, GError **error) { char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag; - guint32 tmp; + char *ip = NULL; + long prefix = 0; gboolean success = FALSE; - shvarFile *network_ifcfg; char *value; + guint32 tmp; g_return_val_if_fail (which >= -1, FALSE); g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (network_file != NULL, FALSE); - g_return_val_if_fail (addr != NULL, FALSE); + g_return_val_if_fail (out_address != NULL, FALSE); + g_return_val_if_fail (*out_address == NULL, FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); @@ -651,82 +358,73 @@ read_full_ip4_address (shvarFile *ifcfg, gw_tag = get_numbered_tag ("GATEWAY", which); /* IP address */ - if (!read_ip4_address (ifcfg, ip_tag, &tmp, error)) - goto done; - if (tmp) - nm_ip4_address_set_address (addr, tmp); - else if (!nm_ip4_address_get_address (addr)) { - success = TRUE; + if (!read_ip4_address (ifcfg, ip_tag, &ip, error)) goto done; + if (!ip) { + if (base_addr) + ip = g_strdup (nm_ip_address_get_address (base_addr)); + else { + success = TRUE; + goto done; + } } /* Gateway */ - if (!read_ip4_address (ifcfg, gw_tag, &tmp, error)) - goto done; - if (tmp) - nm_ip4_address_set_gateway (addr, tmp); - else { - gboolean read_success; - - /* If no gateway in the ifcfg, try /etc/sysconfig/network instead */ - network_ifcfg = svOpenFile (network_file, NULL); - if (network_ifcfg) { - read_success = read_ip4_address (network_ifcfg, "GATEWAY", &tmp, error); - svCloseFile (network_ifcfg); - if (!read_success) - goto done; - nm_ip4_address_set_gateway (addr, tmp); - } + if (out_gateway && !*out_gateway) { + if (!read_ip4_address (ifcfg, gw_tag, out_gateway, error)) + goto done; } /* Prefix */ value = svGetValue (ifcfg, prefix_tag, FALSE); if (value) { - long int prefix; - errno = 0; prefix = strtol (value, NULL, 10); - if (errno || prefix <= 0 || prefix > 32) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + if (errno || prefix < 0) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 prefix '%s'", value); g_free (value); goto done; } - nm_ip4_address_set_prefix (addr, (guint32) prefix); g_free (value); } /* Fall back to NETMASK if no PREFIX was specified */ - if (!nm_ip4_address_get_prefix (addr)) { - if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error)) + if (prefix == 0) { + if (!read_ip4_address (ifcfg, netmask_tag, &value, error)) goto done; - if (tmp) - nm_ip4_address_set_prefix (addr, nm_utils_ip4_netmask_to_prefix (tmp)); + if (value) { + inet_pton (AF_INET, value, &tmp); + prefix = nm_utils_ip4_netmask_to_prefix (tmp); + g_free (value); + } } - /* Try to autodetermine the prefix for the address' class */ - if (!nm_ip4_address_get_prefix (addr)) { - guint32 prefix = 0; + if (prefix == 0 && base_addr) + prefix = nm_ip_address_get_prefix (base_addr); - prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr)); - nm_ip4_address_set_prefix (addr, prefix); + /* Try to autodetermine the prefix for the address' class */ + if (prefix == 0) { + if (inet_pton (AF_INET, ip, &tmp) == 1) { + prefix = nm_utils_ip4_get_default_prefix (tmp); - value = svGetValue (ifcfg, ip_tag, FALSE); - PARSE_WARNING ("missing %s, assuming %s/%u", prefix_tag, value, prefix); - g_free (value); + PARSE_WARNING ("missing %s, assuming %s/%ld", prefix_tag, ip, prefix); + } } /* Validate the prefix */ - if (nm_ip4_address_get_prefix (addr) > 32) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing or invalid IP4 prefix '%d'", - nm_ip4_address_get_prefix (addr)); + if (prefix == 0) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IP4 prefix"); goto done; } - success = TRUE; + *out_address = nm_ip_address_new (AF_INET, ip, prefix, error); + if (*out_address) + success = TRUE; done: + g_free (ip); g_free (ip_tag); g_free (prefix_tag); g_free (netmask_tag); @@ -740,12 +438,12 @@ static gboolean read_one_ip4_route (shvarFile *ifcfg, const char *network_file, guint32 which, - NMIP4Route **out_route, + NMIPRoute **out_route, GError **error) { - NMIP4Route *route; char *ip_tag, *netmask_tag, *gw_tag, *metric_tag, *value; - guint32 tmp; + char *dest = NULL, *next_hop = NULL; + gint64 prefix, metric; gboolean success = FALSE; g_return_val_if_fail (ifcfg != NULL, FALSE); @@ -755,75 +453,72 @@ read_one_ip4_route (shvarFile *ifcfg, if (error) g_return_val_if_fail (*error == NULL, FALSE); - route = nm_ip4_route_new (); - ip_tag = g_strdup_printf ("ADDRESS%u", which); netmask_tag = g_strdup_printf ("NETMASK%u", which); gw_tag = g_strdup_printf ("GATEWAY%u", which); metric_tag = g_strdup_printf ("METRIC%u", which); /* Destination */ - if (!read_ip4_address (ifcfg, ip_tag, &tmp, error)) + if (!read_ip4_address (ifcfg, ip_tag, &dest, error)) goto out; - if (!tmp) { + if (!dest) { /* Check whether IP is missing or 0.0.0.0 */ char *val; val = svGetValue (ifcfg, ip_tag, FALSE); if (!val) { - nm_ip4_route_unref (route); - route = NULL; + *out_route = NULL; success = TRUE; /* missing route = success */ goto out; } g_free (val); } - nm_ip4_route_set_dest (route, tmp); /* Next hop */ - if (!read_ip4_address (ifcfg, gw_tag, &tmp, error)) + if (!read_ip4_address (ifcfg, gw_tag, &next_hop, error)) goto out; - /* No need to check tmp, because we don't make distinction between missing GATEWAY IP and 0.0.0.0 */ - nm_ip4_route_set_next_hop (route, tmp); + /* We don't make distinction between missing GATEWAY IP and 0.0.0.0 */ /* Prefix */ - if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error)) + if (!read_ip4_address (ifcfg, netmask_tag, &value, error)) goto out; - if (tmp) - nm_ip4_route_set_prefix (route, nm_utils_ip4_netmask_to_prefix (tmp)); + if (value) { + guint32 netmask; - /* Validate the prefix */ - if ( !nm_ip4_route_get_prefix (route) - || nm_ip4_route_get_prefix (route) > 32) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing or invalid IP4 prefix '%d'", - nm_ip4_route_get_prefix (route)); + inet_pton (AF_INET, value, &netmask); + prefix = nm_utils_ip4_netmask_to_prefix (netmask); + g_free (value); + if (prefix == 0 || netmask != nm_utils_ip4_prefix_to_netmask (prefix)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 netmask '%s' \"%s\"", netmask_tag, nm_utils_inet4_ntop (netmask, NULL)); + goto out; + } + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IP4 route element '%s'", netmask_tag); goto out; } /* Metric */ value = svGetValue (ifcfg, metric_tag, FALSE); if (value) { - long int metric; - - errno = 0; - metric = strtol (value, NULL, 10); - if (errno || metric < 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + metric = nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); + if (metric < 0) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route metric '%s'", value); g_free (value); goto out; } - nm_ip4_route_set_metric (route, (guint32) metric); g_free (value); - } + } else + metric = -1; - *out_route = route; - success = TRUE; + *out_route = nm_ip_route_new (AF_INET, dest, prefix, next_hop, metric, error); + if (*out_route) + success = TRUE; out: - if (!success && route) - nm_ip4_route_unref (route); - + g_free (dest); + g_free (next_hop); g_free (ip_tag); g_free (netmask_tag); g_free (gw_tag); @@ -832,17 +527,16 @@ out: } static gboolean -read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error) +read_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError **error) { char *contents = NULL; gsize len = 0; char **lines = NULL, **iter; GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; GMatchInfo *match_info; - NMIP4Route *route; - guint32 ip4_addr; - char *dest = NULL, *prefix = NULL, *metric = NULL; - long int prefix_int, metric_int; + NMIPRoute *route = NULL; + char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; + gint64 prefix_int, metric_int; gboolean success = FALSE; const char *pattern_empty = "^\\s*(\\#.*)?$"; @@ -870,9 +564,6 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError regex_via = g_regex_new (pattern_via, 0, 0, NULL); regex_metric = g_regex_new (pattern_metric, 0, 0, NULL); - /* New NMIP4Route structure */ - route = nm_ip4_route_new (); - /* Iterate through file lines */ lines = g_strsplit_set (contents, "\n\r", -1); for (iter = lines; iter && *iter; iter++) { @@ -888,22 +579,21 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError g_regex_match (regex_to2, *iter, 0, &match_info); if (!g_match_info_matches (match_info)) { g_match_info_free (match_info); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing IP4 route destination address in record: '%s'", *iter); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IP4 route destination address in record: '%s'", *iter); goto error; } } dest = g_match_info_fetch (match_info, 1); if (!strcmp (dest, "default")) strcpy (dest, "0.0.0.0"); - if (inet_pton (AF_INET, dest, &ip4_addr) != 1) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP4 route destination address '%s'", dest); + if (!nm_utils_ipaddr_valid (AF_INET, dest)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 route destination address '%s'", dest); g_free (dest); + g_match_info_free (match_info); goto error; } - nm_ip4_route_set_dest (route, ip4_addr); - g_free (dest); /* Prefix - is optional; 32 if missing */ prefix = g_match_info_fetch (match_info, 2); @@ -913,58 +603,62 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError errno = 0; prefix_int = strtol (prefix, NULL, 10); if (errno || prefix_int <= 0 || prefix_int > 32) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP4 route destination prefix '%s'", prefix); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP4 route destination prefix '%s'", prefix); + g_free (dest); g_free (prefix); goto error; } } - nm_ip4_route_set_prefix (route, (guint32) prefix_int); g_free (prefix); /* Next hop */ g_regex_match (regex_via, *iter, 0, &match_info); if (g_match_info_matches (match_info)) { - char *next_hop = g_match_info_fetch (match_info, 1); - if (inet_pton (AF_INET, next_hop, &ip4_addr) != 1) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + next_hop = g_match_info_fetch (match_info, 1); + if (!nm_utils_ipaddr_valid (AF_INET, next_hop)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route gateway address '%s'", next_hop); g_match_info_free (match_info); + g_free (dest); g_free (next_hop); goto error; } - g_free (next_hop); } else { /* we don't make distinction between missing GATEWAY IP and 0.0.0.0 */ - ip4_addr = 0; + next_hop = NULL; } - nm_ip4_route_set_next_hop (route, ip4_addr); g_match_info_free (match_info); /* Metric */ g_regex_match (regex_metric, *iter, 0, &match_info); - metric_int = 0; + 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) { g_match_info_free (match_info); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP4 route metric '%s'", metric); + g_free (dest); + g_free (next_hop); g_free (metric); goto error; } g_free (metric); } - - nm_ip4_route_set_metric (route, (guint32) metric_int); g_match_info_free (match_info); - if (!nm_setting_ip4_config_add_route (s_ip4, route)) + route = nm_ip_route_new (AF_INET, dest, prefix_int, next_hop, metric_int, error); + if (!route) { + g_free (dest); + g_free (next_hop); + goto error; + } + if (!nm_setting_ip_config_add_route (s_ip4, route)) PARSE_WARNING ("duplicate IP4 route"); - } success = TRUE; @@ -972,7 +666,8 @@ read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError error: g_free (contents); g_strfreev (lines); - nm_ip4_route_unref (route); + if (route) + nm_ip_route_unref (route); g_regex_unref (regex_to1); g_regex_unref (regex_to2); g_regex_unref (regex_via); @@ -986,15 +681,12 @@ parse_full_ip6_address (shvarFile *ifcfg, const char *network_file, const char *addr_str, int i, - NMIP6Address **out_address, + NMIPAddress **out_address, GError **error) { - NMIP6Address *addr = NULL; char **list; char *ip_val, *prefix_val; - shvarFile *network_ifcfg; - char *value = NULL; - struct in6_addr tmp = IN6ADDR_ANY_INIT; + long prefix; gboolean success = FALSE; g_return_val_if_fail (addr_str != NULL, FALSE); @@ -1006,77 +698,33 @@ parse_full_ip6_address (shvarFile *ifcfg, /* Split the address and prefix */ list = g_strsplit_set (addr_str, "/", 2); if (g_strv_length (list) < 1) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 address '%s'", addr_str); goto error; } ip_val = list[0]; - prefix_val = list[1]; - addr = nm_ip6_address_new (); - /* IP address */ - if (!parse_ip6_address (ip_val, &tmp, error)) - goto error; - if (IN6_IS_ADDR_UNSPECIFIED (&tmp)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP6 address '%s'", ip_val); - goto error; - } - nm_ip6_address_set_address (addr, &tmp); - - /* Prefix */ + prefix_val = list[1]; if (prefix_val) { - long int prefix; - errno = 0; prefix = strtol (prefix_val, NULL, 10); if (errno || prefix <= 0 || prefix > 128) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 prefix '%s'", prefix_val); goto error; } - nm_ip6_address_set_prefix (addr, (guint32) prefix); } else { /* Missing prefix is treated as prefix of 64 */ - nm_ip6_address_set_prefix (addr, 64); + prefix = 64; } - /* Gateway */ - tmp = in6addr_any; - value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE); - if (i != 0) { - /* We don't support gateways for IPV6ADDR_SECONDARIES yet */ - g_free (value); - value = NULL; - } - if (!value) { - /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */ - network_ifcfg = svOpenFile (network_file, NULL); - if (network_ifcfg) { - value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE); - svCloseFile (network_ifcfg); - } - } - if (value) { - char *ptr; - - if ((ptr = strchr (value, '%')) != NULL) - *ptr = '\0'; /* remove %interface prefix if present */ - if (!parse_ip6_address (value, &tmp, error)) - goto error; - nm_ip6_address_set_gateway (addr, &tmp); - } - - *out_address = addr; - success = TRUE; + *out_address = nm_ip_address_new (AF_INET6, ip_val, prefix, error); + if (*out_address) + success = TRUE; error: - if (!success && addr) - nm_ip6_address_unref (addr); - g_strfreev (list); - g_free (value); return success; } @@ -1088,17 +736,16 @@ error: #define IPV6_ADDR_REGEX "[0-9A-Fa-f:.]+" static gboolean -read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error) +read_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error) { char *contents = NULL; gsize len = 0; char **lines = NULL, **iter; GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric; GMatchInfo *match_info; - NMIP6Route *route; - struct in6_addr ip6_addr; - char *dest = NULL, *prefix = NULL, *metric = NULL; - long int prefix_int, metric_int; + NMIPRoute *route = NULL; + char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL; + gint64 prefix_int, metric_int; gboolean success = FALSE; const char *pattern_empty = "^\\s*(\\#.*)?$"; @@ -1126,9 +773,6 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro regex_via = g_regex_new (pattern_via, 0, 0, NULL); regex_metric = g_regex_new (pattern_metric, 0, 0, NULL); - /* New NMIP6Route structure */ - route = nm_ip6_route_new (); - /* Iterate through file lines */ lines = g_strsplit_set (contents, "\n\r", -1); for (iter = lines; iter && *iter; iter++) { @@ -1144,27 +788,19 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro g_regex_match (regex_to2, *iter, 0, &match_info); if (!g_match_info_matches (match_info)) { g_match_info_free (match_info); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing IP6 route destination address in record: '%s'", *iter); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IP6 route destination address in record: '%s'", *iter); goto error; } } dest = g_match_info_fetch (match_info, 1); if (!g_strcmp0 (dest, "default")) { /* Ignore default route - NM handles it internally */ - g_free (dest); + g_clear_pointer (&dest, g_free); g_match_info_free (match_info); PARSE_WARNING ("ignoring manual default route: '%s' (%s)", *iter, filename); continue; } - if (inet_pton (AF_INET6, dest, &ip6_addr) != 1) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP6 route destination address '%s'", dest); - g_free (dest); - goto error; - } - nm_ip6_route_set_dest (route, &ip6_addr); - g_free (dest); /* Prefix - is optional; 128 if missing */ prefix = g_match_info_fetch (match_info, 2); @@ -1174,56 +810,60 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro errno = 0; prefix_int = strtol (prefix, NULL, 10); if (errno || prefix_int <= 0 || prefix_int > 128) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid IP6 route destination prefix '%s'", prefix); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP6 route destination prefix '%s'", prefix); + g_free (dest); g_free (prefix); goto error; } } - nm_ip6_route_set_prefix (route, (guint32) prefix_int); g_free (prefix); /* Next hop */ g_regex_match (regex_via, *iter, 0, &match_info); if (g_match_info_matches (match_info)) { - char *next_hop = g_match_info_fetch (match_info, 1); - if (inet_pton (AF_INET6, next_hop, &ip6_addr) != 1) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + next_hop = g_match_info_fetch (match_info, 1); + if (!nm_utils_ipaddr_valid (AF_INET6, next_hop)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv6 route nexthop address '%s'", next_hop); g_match_info_free (match_info); + g_free (dest); g_free (next_hop); goto error; } - g_free (next_hop); } else { /* Missing "via" is taken as :: */ - ip6_addr = in6addr_any; + next_hop = NULL; } - nm_ip6_route_set_next_hop (route, &ip6_addr); g_match_info_free (match_info); /* Metric */ g_regex_match (regex_metric, *iter, 0, &match_info); - metric_int = 0; + 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) { g_match_info_free (match_info); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 route metric '%s'", metric); + g_free (dest); + g_free (next_hop); g_free (metric); goto error; } g_free (metric); } - - nm_ip6_route_set_metric (route, (guint32) metric_int); g_match_info_free (match_info); - if (!nm_setting_ip6_config_add_route (s_ip6, route)) + route = nm_ip_route_new (AF_INET6, dest, prefix_int, next_hop, metric_int, error); + g_free (dest); + g_free (next_hop); + if (!route) + goto error; + if (!nm_setting_ip_config_add_route (s_ip6, route)) PARSE_WARNING ("duplicate IP6 route"); } @@ -1232,7 +872,8 @@ read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **erro error: g_free (contents); g_strfreev (lines); - nm_ip6_route_unref (route); + if (route) + nm_ip_route_unref (route); g_regex_unref (regex_to1); g_regex_unref (regex_to2); g_regex_unref (regex_via); @@ -1245,19 +886,19 @@ error: static NMSetting * make_ip4_setting (shvarFile *ifcfg, const char *network_file, - const char *iscsiadm_path, GError **error) { - NMSettingIP4Config *s_ip4 = NULL; + NMSettingIPConfig *s_ip4 = NULL; char *value = NULL; char *route_path = NULL; char *method; + char *gateway = NULL; gint32 i; shvarFile *network_ifcfg; shvarFile *route_ifcfg; gboolean never_default = FALSE; - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); /* First check if DEFROUTE is set for this device; DEFROUTE has the * opposite meaning from never-default. The default if DEFROUTE is not @@ -1297,32 +938,22 @@ make_ip4_setting (shvarFile *ifcfg, method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; } else if (!g_ascii_strcasecmp (value, "static")) { method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - } else if (!g_ascii_strcasecmp (value, "ibft")) { - g_free (value); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL); - /* iSCSI Boot Firmware Table: need to read values from the iSCSI - * firmware for this device and create the IP4 setting using those. - */ - if (fill_ip4_setting_from_ibft (ifcfg, s_ip4, iscsiadm_path, error)) - return NM_SETTING (s_ip4); - g_object_unref (s_ip4); - return NULL; } else if (!g_ascii_strcasecmp (value, "autoip")) { g_free (value); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); return NM_SETTING (s_ip4); } else if (!g_ascii_strcasecmp (value, "shared")) { g_free (value); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); return NM_SETTING (s_ip4); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown BOOTPROTO '%s'", value); g_free (value); goto done; @@ -1330,11 +961,11 @@ make_ip4_setting (shvarFile *ifcfg, g_free (value); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, method, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE), - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, - NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE), + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE), + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", FALSE), NULL); if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) @@ -1344,11 +975,11 @@ make_ip4_setting (shvarFile *ifcfg, if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE); if (value && strlen (value)) - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, value, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, value, NULL); g_free (value); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, svTrueValue (ifcfg, "DHCP_SEND_HOSTNAME", TRUE), NULL); @@ -1364,16 +995,12 @@ make_ip4_setting (shvarFile *ifcfg, * the legacy 'network' service (ifup-eth). */ for (i = -1; i < 256; i++) { - NMIP4Address *addr = NULL; + NMIPAddress *addr = NULL; - addr = nm_ip4_address_new (); - if (!read_full_ip4_address (ifcfg, network_file, i, addr, error)) { - nm_ip4_address_unref (addr); + if (!read_full_ip4_address (ifcfg, network_file, i, NULL, &addr, &gateway, error)) goto done; - } - if (!nm_ip4_address_get_address (addr)) { - nm_ip4_address_unref (addr); + if (!addr) { /* The first mandatory variable is 2-indexed (IPADDR2) * Variables IPADDR, IPADDR0 and IPADDR1 are optional */ if (i > 1) @@ -1381,39 +1008,49 @@ make_ip4_setting (shvarFile *ifcfg, continue; } - if (!nm_setting_ip4_config_add_address (s_ip4, addr)) + if (!nm_setting_ip_config_add_address (s_ip4, addr)) PARSE_WARNING ("duplicate IP4 address"); - nm_ip4_address_unref (addr); + nm_ip_address_unref (addr); } + /* Gateway */ + if (!gateway) { + network_ifcfg = svOpenFile (network_file, NULL); + if (network_ifcfg) { + gboolean read_success; + + read_success = read_ip4_address (network_ifcfg, "GATEWAY", &gateway, error); + svCloseFile (network_ifcfg); + if (!read_success) + goto done; + } + } + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); + /* DNS servers * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) */ for (i = 1; i <= 10; i++) { char *tag; - guint32 dns; - struct in6_addr ip6_dns; tag = g_strdup_printf ("DNS%u", i); - if (!read_ip4_address (ifcfg, tag, &dns, error)) { - gboolean valid = TRUE; - - /* Ignore IPv6 addresses */ - dns = 0; - value = svGetValue (ifcfg, tag, FALSE); - if (value) - valid = parse_ip6_address (value, &ip6_dns, NULL); - g_free (value); - - if (!valid) { + value = svGetValue (ifcfg, tag, FALSE); + if (value) { + if (nm_utils_ipaddr_valid (AF_INET, value)) { + if (!nm_setting_ip_config_add_dns (s_ip4, value)) + PARSE_WARNING ("duplicate DNS server %s", tag); + } else if (nm_utils_ipaddr_valid (AF_INET6, value)) { + /* Ignore IPv6 addresses */ + } else { + PARSE_WARNING ("invalid DNS server address %s", value); g_free (tag); + g_free (value); goto done; } - g_clear_error (error); + + g_free (value); } - if (dns && !nm_setting_ip4_config_add_dns (s_ip4, dns)) - PARSE_WARNING ("duplicate DNS server %s", tag); g_free (tag); } @@ -1427,7 +1064,7 @@ make_ip4_setting (shvarFile *ifcfg, char **item; for (item = searches; *item; item++) { if (strlen (*item)) { - if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item)) + if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) PARSE_WARNING ("duplicate DNS domain '%s'", *item); } } @@ -1439,7 +1076,7 @@ make_ip4_setting (shvarFile *ifcfg, /* Static routes - route- file */ route_path = utils_get_route_path (ifcfg->fileName); if (!route_path) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Could not get route file path for '%s'", ifcfg->fileName); goto done; } @@ -1450,7 +1087,7 @@ make_ip4_setting (shvarFile *ifcfg, route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE); if (route_ifcfg) { for (i = 0; i < 256; i++) { - NMIP4Route *route = NULL; + NMIPRoute *route = NULL; if (!read_one_ip4_route (route_ifcfg, network_file, i, &route, error)) { svCloseFile (route_ifcfg); @@ -1460,9 +1097,9 @@ make_ip4_setting (shvarFile *ifcfg, if (!route) break; - if (!nm_setting_ip4_config_add_route (s_ip4, route)) + if (!nm_setting_ip_config_add_route (s_ip4, route)) PARSE_WARNING ("duplicate IP4 route"); - nm_ip4_route_unref (route); + nm_ip_route_unref (route); } svCloseFile (route_ifcfg); } @@ -1472,7 +1109,7 @@ make_ip4_setting (shvarFile *ifcfg, } /* Legacy value NM used for a while but is incorrect (rh #459370) */ - if (!nm_setting_ip4_config_get_num_dns_searches (s_ip4)) { + if (!nm_setting_ip_config_get_num_dns_searches (s_ip4)) { value = svGetValue (ifcfg, "SEARCH", FALSE); if (value) { char **searches = NULL; @@ -1482,7 +1119,7 @@ make_ip4_setting (shvarFile *ifcfg, char **item; for (item = searches; *item; item++) { if (strlen (*item)) { - if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item)) + if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) PARSE_WARNING ("duplicate DNS search '%s'", *item); } } @@ -1495,27 +1132,29 @@ make_ip4_setting (shvarFile *ifcfg, return NM_SETTING (s_ip4); done: + g_free (gateway); g_free (route_path); g_object_unref (s_ip4); return NULL; } static void -read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *network_file) +read_aliases (NMSettingIPConfig *s_ip4, const char *filename, const char *network_file) { GDir *dir; char *dirname, *base; shvarFile *parsed; - NMIP4Address *base_addr; + NMIPAddress *base_addr; GError *err = NULL; g_return_if_fail (s_ip4 != NULL); g_return_if_fail (filename != NULL); - base_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - if (!base_addr) + if (nm_setting_ip_config_get_num_addresses (s_ip4) == 0) return; + base_addr = nm_setting_ip_config_get_address (s_ip4, 0); + dirname = g_path_get_dirname (filename); g_return_if_fail (dirname != NULL); base = g_path_get_basename (filename); @@ -1524,7 +1163,7 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo dir = g_dir_open (dirname, 0, &err); if (dir) { const char *item; - NMIP4Address *addr; + NMIPAddress *addr; gboolean ok; while ((item = g_dir_read_name (dir))) { @@ -1573,18 +1212,19 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo continue; } - addr = nm_ip4_address_dup (base_addr); - ok = read_full_ip4_address (parsed, network_file, -1, addr, &err); + addr = NULL; + ok = read_full_ip4_address (parsed, network_file, -1, base_addr, &addr, NULL, &err); svCloseFile (parsed); if (ok) { - if (!NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, device))) + nm_ip_address_set_attribute (addr, "label", g_variant_new_string (device)); + if (!nm_setting_ip_config_add_address (s_ip4, addr)) PARSE_WARNING ("duplicate IP4 address in alias file %s", item); } else { PARSE_WARNING ("error reading IP4 address from alias file '%s': %s", full_path, err ? err->message : "no address"); g_clear_error (&err); } - nm_ip4_address_unref (addr); + nm_ip_address_unref (addr); g_free (device); g_free (full_path); @@ -1603,10 +1243,9 @@ read_aliases (NMSettingIP4Config *s_ip4, const char *filename, const char *netwo static NMSetting * make_ip6_setting (shvarFile *ifcfg, const char *network_file, - const char *iscsiadm_path, GError **error) { - NMSettingIP6Config *s_ip6 = NULL; + NMSettingIPConfig *s_ip6 = NULL; char *value = NULL; char *str_value; char *route6_path = NULL; @@ -1621,7 +1260,7 @@ make_ip6_setting (shvarFile *ifcfg, char *ip6_privacy_str; NMSettingIP6ConfigPrivacy ip6_privacy_val; - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); /* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the * opposite meaning from never-default. The default if IPV6_DEFROUTE is not @@ -1718,11 +1357,11 @@ make_ip6_setting (shvarFile *ifcfg, g_free (ip6_privacy_str); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, method, - NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE), - NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, - NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE), + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE), + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, + NM_SETTING_IP_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE), NM_SETTING_IP6_CONFIG_IP6_PRIVACY, ip6_privacy_val, NULL); @@ -1735,7 +1374,7 @@ make_ip6_setting (shvarFile *ifcfg, /* METHOD_AUTO may trigger DHCPv6, so save the hostname to send to DHCP */ value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE); if (value && value[0]) - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME, value, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, value, NULL); g_free (value); } @@ -1757,26 +1396,51 @@ make_ip6_setting (shvarFile *ifcfg, list = g_strsplit_set (value, " ", 0); g_free (value); for (iter = list, i = 0; iter && *iter; iter++, i++) { - NMIP6Address *addr = NULL; + NMIPAddress *addr = NULL; if (!parse_full_ip6_address (ifcfg, network_file, *iter, i, &addr, error)) { g_strfreev (list); goto error; } - if (!nm_setting_ip6_config_add_address (s_ip6, addr)) + if (!nm_setting_ip_config_add_address (s_ip6, addr)) PARSE_WARNING ("duplicate IP6 address"); - nm_ip6_address_unref (addr); + nm_ip_address_unref (addr); } g_strfreev (list); + /* Gateway */ + if (nm_setting_ip_config_get_num_addresses (s_ip6)) { + value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE); + if (!value) { + /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */ + network_ifcfg = svOpenFile (network_file, NULL); + if (network_ifcfg) { + value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE); + svCloseFile (network_ifcfg); + } + } + if (value) { + char *ptr; + if ((ptr = strchr (value, '%')) != NULL) + *ptr = '\0'; /* remove %interface prefix if present */ + if (!nm_utils_ipaddr_valid (AF_INET6, value)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IP6 address '%s'", value); + g_free (value); + goto error; + } + + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, value, NULL); + g_free (value); + } + } + /* DNS servers * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) */ for (i = 1; i <= 10; i++) { char *tag; - struct in6_addr ip6_dns; - guint32 ip4_addr; tag = g_strdup_printf ("DNS%u", i); value = svGetValue (ifcfg, tag, FALSE); @@ -1785,30 +1449,28 @@ make_ip6_setting (shvarFile *ifcfg, break; /* all done */ } - ip6_dns = in6addr_any; - if (parse_ip6_address (value, &ip6_dns, NULL)) { - if (!IN6_IS_ADDR_UNSPECIFIED (&ip6_dns) && !nm_setting_ip6_config_add_dns (s_ip6, &ip6_dns)) + if (nm_utils_ipaddr_valid (AF_INET6, value)) { + if (!nm_setting_ip_config_add_dns (s_ip6, value)) PARSE_WARNING ("duplicate DNS server %s", tag); + } else if (nm_utils_ipaddr_valid (AF_INET, value)) { + /* Ignore IPv4 addresses */ } else { - /* Maybe an IPv4 address? If so ignore it */ - if (inet_pton (AF_INET, value, &ip4_addr) != 1) { - g_free (tag); - g_free (value); - PARSE_WARNING ("duplicate IP6 address"); - goto error; - } + PARSE_WARNING ("invalid DNS server address %s", value); + g_free (tag); + g_free (value); + goto error; } g_free (tag); g_free (value); } - /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */ + /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ /* Read static routes from route6- file */ route6_path = utils_get_route6_path (ifcfg->fileName); if (!route6_path) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Could not get route6 file path for '%s'", ifcfg->fileName); goto error; } @@ -1929,7 +1591,7 @@ read_dcb_app (shvarFile *ifcfg, if (success) success = (priority >= 0 && priority <= 7); if (!success) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid %s value '%s' (expected 0 - 7)", tmp, val); } @@ -1978,7 +1640,8 @@ read_dcb_bool_array (shvarFile *ifcfg, val = g_strstrip (val); if (strlen (val) != 8) { PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, val); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "boolean array must be 8 characters"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "boolean array must be 8 characters"); goto out; } @@ -1986,7 +1649,8 @@ read_dcb_bool_array (shvarFile *ifcfg, for (i = 0; i < 8; i++) { if (val[i] != '0' && val[i] != '1') { PARSE_WARNING ("invalid %s value '%s': not all 0s and 1s", prop, val); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid boolean digit"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid boolean digit"); goto out; } set_func (s_dcb, i, (val[i] == '1')); @@ -2027,7 +1691,8 @@ read_dcb_uint_array (shvarFile *ifcfg, val = g_strstrip (val); if (strlen (val) != 8) { PARSE_WARNING ("%s value '%s' must be 8 characters long", prop, val); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "uint array must be 8 characters"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "uint array must be 8 characters"); goto out; } @@ -2040,7 +1705,8 @@ read_dcb_uint_array (shvarFile *ifcfg, else { PARSE_WARNING ("invalid %s value '%s': not 0 - 7%s", prop, val, f_allowed ? " or 'f'" : ""); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid uint digit"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid uint digit"); goto out; } } @@ -2081,14 +1747,16 @@ read_dcb_percent_array (shvarFile *ifcfg, split = g_strsplit_set (val, ",", 0); if (!split || (g_strv_length (split) != 8)) { PARSE_WARNING ("invalid %s percentage list value '%s'", prop, val); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "percent array must be 8 elements"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "percent array must be 8 elements"); goto out; } for (iter = split, i = 0; iter && *iter; iter++, i++) { if (!get_int (*iter, &tmp) || tmp < 0 || tmp > 100) { PARSE_WARNING ("invalid %s percentage value '%s'", prop, *iter); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid percent element"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid percent element"); goto out; } set_func (s_dcb, i, (guint) tmp); @@ -2097,7 +1765,8 @@ read_dcb_percent_array (shvarFile *ifcfg, if (sum_pct && (sum != 100)) { PARSE_WARNING ("%s percentages do not equal 100%%", prop); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid percentage sum"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid percentage sum"); goto out; } @@ -2146,7 +1815,8 @@ make_dcb_setting (shvarFile *ifcfg, g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL); else { PARSE_WARNING ("invalid FCoE mode '%s'", val); - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid FCoE mode"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid FCoE mode"); g_free (val); g_object_unref (s_dcb); return FALSE; @@ -2297,7 +1967,7 @@ add_one_wep_key (shvarFile *ifcfg, while (*p) { if (!g_ascii_isxdigit (*p)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid hexadecimal WEP key."); goto out; } @@ -2311,7 +1981,7 @@ add_one_wep_key (shvarFile *ifcfg, while (*p) { if (!g_ascii_isprint ((int) (*p))) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid ASCII WEP key."); goto out; } @@ -2333,7 +2003,8 @@ add_one_wep_key (shvarFile *ifcfg, g_free (key); success = TRUE; } else - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid WEP key length."); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WEP key length."); out: g_free (value); @@ -2418,7 +2089,7 @@ make_wep_setting (shvarFile *ifcfg, default_key_idx--; /* convert to [0...3] */ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid default WEP key '%s'", value); g_free (value); goto error; @@ -2459,7 +2130,7 @@ make_wep_setting (shvarFile *ifcfg, } else if (!strcmp (lcase, "restricted")) { g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WEP authentication algorithm '%s'", lcase); g_free (lcase); @@ -2481,7 +2152,7 @@ make_wep_setting (shvarFile *ifcfg, auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); if (auth_alg && !strcmp (auth_alg, "shared")) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "WEP Shared Key authentication is invalid for " "unencrypted connections."); goto error; @@ -2570,7 +2241,7 @@ fill_wpa_ciphers (shvarFile *ifcfg, static char * parse_wpa_psk (shvarFile *ifcfg, const char *file, - const GByteArray *ssid, + GBytes *ssid, GError **error) { shvarFile *keys_ifcfg; @@ -2609,7 +2280,7 @@ parse_wpa_psk (shvarFile *ifcfg, /* Verify the hex PSK; 64 digits */ while (*p) { if (!g_ascii_isxdigit (*p++)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WPA_PSK (contains non-hexadecimal characters)"); goto out; } @@ -2627,7 +2298,7 @@ parse_wpa_psk (shvarFile *ifcfg, /* Length check */ if (strlen (hashed) < 8 || strlen (hashed) > 63) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WPA_PSK (passphrases must be between " "8 and 63 characters long (inclusive))"); g_free (hashed); @@ -2637,7 +2308,7 @@ parse_wpa_psk (shvarFile *ifcfg, } if (!hashed) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); goto out; } @@ -2660,7 +2331,7 @@ eap_simple_reader (const char *eap_method, value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); if (!value) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", eap_method); return FALSE; @@ -2680,7 +2351,7 @@ eap_simple_reader (const char *eap_method, } if (!value) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", eap_method); return FALSE; @@ -2741,7 +2412,7 @@ eap_tls_reader (const char *eap_method, value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); if (!value) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", eap_method); return FALSE; @@ -2788,7 +2459,7 @@ eap_tls_reader (const char *eap_method, } if (!privkey_password) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", pk_pw_key, eap_method); @@ -2799,7 +2470,7 @@ eap_tls_reader (const char *eap_method, /* The private key itself */ privkey = svGetValue (ifcfg, pk_key, FALSE); if (!privkey) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", pk_key, eap_method); @@ -2836,7 +2507,7 @@ eap_tls_reader (const char *eap_method, || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { client_cert = svGetValue (ifcfg, cli_cert_key, FALSE); if (!client_cert) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", cli_cert_key, eap_method); @@ -2912,7 +2583,7 @@ eap_peap_reader (const char *eap_method, else if (!strcmp (peapver, "1")) g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_PEAP_VERSION value '%s'", peapver); goto done; @@ -2928,7 +2599,7 @@ eap_peap_reader (const char *eap_method, inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); if (!inner_auth) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_INNER_AUTH_METHODS."); goto done; } @@ -2948,7 +2619,7 @@ eap_peap_reader (const char *eap_method, if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) goto done; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", *iter); goto done; @@ -2961,7 +2632,7 @@ eap_peap_reader (const char *eap_method, } if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No valid IEEE_8021X_INNER_AUTH_METHODS found."); goto done; } @@ -3015,7 +2686,7 @@ eap_ttls_reader (const char *eap_method, tmp = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); if (!tmp) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_INNER_AUTH_METHODS."); goto done; } @@ -3047,7 +2718,7 @@ eap_ttls_reader (const char *eap_method, goto done; g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + STRLEN ("eap-")), NULL); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", *iter); goto done; @@ -3115,7 +2786,7 @@ eap_fast_reader (const char *eap_method, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, pac_prov_str, NULL); if (!pac_file && !(allow_unauth || allow_auth)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "IEEE_8021X_PAC_FILE not provided and EAP-FAST automatic PAC provisioning disabled."); goto done; } @@ -3126,7 +2797,7 @@ eap_fast_reader (const char *eap_method, inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE); if (!inner_auth) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_INNER_AUTH_METHODS."); goto done; } @@ -3142,7 +2813,7 @@ eap_fast_reader (const char *eap_method, if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) goto done; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", *iter); goto done; @@ -3155,7 +2826,7 @@ eap_fast_reader (const char *eap_method, } if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No valid IEEE_8021X_INNER_AUTH_METHODS found."); goto done; } @@ -3205,8 +2876,7 @@ read_8021x_list_value (shvarFile *ifcfg, const char *prop_name) { char *value; - char **strv, **iter; - GSList *gslist = NULL; + char **strv; g_return_if_fail (ifcfg != NULL); g_return_if_fail (ifcfg_var_name != NULL); @@ -3217,16 +2887,8 @@ read_8021x_list_value (shvarFile *ifcfg, return; strv = g_strsplit_set (value, " \t", 0); - for (iter = strv; iter && *iter; iter++) { - if (*iter[0] == '\0') - continue; - gslist = g_slist_prepend (gslist, *iter); - } - if (gslist) { - gslist = g_slist_reverse (gslist); - g_object_set (setting, prop_name, gslist, NULL); - g_slist_free (gslist); - } + if (strv && strv[0]) + g_object_set (setting, prop_name, strv, NULL); g_strfreev (strv); g_free (value); } @@ -3245,7 +2907,7 @@ fill_8021x (shvarFile *ifcfg, value = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE); if (!value) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_EAP_METHODS for key management '%s'", key_mgmt); return NULL; @@ -3266,7 +2928,7 @@ fill_8021x (shvarFile *ifcfg, char *lower = NULL; lower = g_ascii_strdown (*iter, -1); - while (eap->method && !found) { + while (eap->method) { if (strcmp (eap->method, lower)) goto next; @@ -3287,6 +2949,7 @@ fill_8021x (shvarFile *ifcfg, } nm_setting_802_1x_add_eap_method (s_8021x, lower); found = TRUE; + break; next: eap++; @@ -3298,7 +2961,7 @@ fill_8021x (shvarFile *ifcfg, } if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No valid EAP methods found in IEEE_8021X_EAP_METHODS."); goto error; } @@ -3334,7 +2997,7 @@ error: static NMSetting * make_wpa_setting (shvarFile *ifcfg, const char *file, - const GByteArray *ssid, + GBytes *ssid, gboolean adhoc, NMSetting8021x **s_8021x, GError **error) @@ -3408,7 +3071,7 @@ make_wpa_setting (shvarFile *ifcfg, } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { /* Adhoc mode is mutually exclusive with any 802.1x-based authentication */ if (adhoc) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", value); goto error; } @@ -3421,7 +3084,7 @@ make_wpa_setting (shvarFile *ifcfg, g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL); g_free (lower); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown wireless KEY_MGMT type '%s'", value); goto error; } @@ -3480,7 +3143,7 @@ make_leap_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE); if (!value || !strlen (value)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing LEAP identity"); goto error; } @@ -3504,7 +3167,7 @@ error: static NMSetting * make_wireless_security_setting (shvarFile *ifcfg, const char *file, - const GByteArray *ssid, + GBytes *ssid, gboolean adhoc, NMSetting8021x **s_8021x, GError **error) @@ -3534,118 +3197,110 @@ make_wireless_security_setting (shvarFile *ifcfg, return NULL; /* unencrypted */ } +static char ** +transform_hwaddr_blacklist (const char *blacklist) +{ + char **strv, **iter; + int shift = 0; + + strv = _nm_utils_strsplit_set (blacklist, " \t", 0); + for (iter = strv; iter && *iter; iter++) { + if (shift) { + *(iter - shift) = *iter; + *iter = NULL; + } + if (!nm_utils_hwaddr_valid (*(iter - shift), ETH_ALEN)) { + PARSE_WARNING ("invalid MAC in HWADDR_BLACKLIST '%s'", *(iter - shift)); + g_free (*(iter - shift)); + *(iter - shift) = NULL; + shift++; + } + } + return strv; +} + static NMSetting * make_wireless_setting (shvarFile *ifcfg, GError **error) { NMSettingWireless *s_wireless; - GByteArray *array = NULL; - GSList *macaddr_blacklist = NULL; - char *value; + char *value = NULL; + gint64 chan = 0; s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &array, error)) { - if (array) { - g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - } else { - g_object_unref (s_wireless); - return NULL; + value = svGetValue (ifcfg, "HWADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, value, NULL); + g_free (value); } - array = NULL; - if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &array, error)) { - if (array) { - g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - } else { - PARSE_WARNING ("%s", (*error)->message); - g_clear_error (error); + value = svGetValue (ifcfg, "MACADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, value, NULL); + g_free (value); } value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE); if (value) { - char **list = NULL, **iter; - struct ether_addr addr; + char **strv; - list = g_strsplit_set (value, " \t", 0); - for (iter = list; iter && *iter; iter++) { - if (**iter == '\0') - continue; - if (!ether_aton_r (*iter, &addr)) { - PARSE_WARNING ("invalid MAC in HWADDR_BLACKLIST '%s'", *iter); - continue; - } - macaddr_blacklist = g_slist_prepend (macaddr_blacklist, *iter); - } - if (macaddr_blacklist) { - macaddr_blacklist = g_slist_reverse (macaddr_blacklist); - g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, macaddr_blacklist, NULL); - g_slist_free (macaddr_blacklist); - } + strv = transform_hwaddr_blacklist (value); + g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, strv, NULL); + g_strfreev (strv); g_free (value); - g_strfreev (list); } value = svGetValue (ifcfg, "ESSID", TRUE); if (value) { - gsize ssid_len = 0, value_len = strlen (value); - char *p = value, *tmp; - char buf[33]; + GBytes *bytes = NULL; + gsize ssid_len = 0; + gsize value_len = strlen (value); - ssid_len = value_len; if ( (value_len >= 2) && (value[0] == '"') && (value[value_len - 1] == '"')) { /* Strip the quotes and unescape */ - p = value + 1; + char *p = value + 1; + value[value_len - 1] = '\0'; svUnescape (p); - ssid_len = strlen (p); + bytes = g_bytes_new (p, strlen (p)); } else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) { /* Hex representation */ if (value_len % 2) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", value); g_free (value); goto error; } - p = value + 2; - while (*p) { - if (!g_ascii_isxdigit (*p)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)", - value, *p); - g_free (value); - goto error; - } - p++; + bytes = nm_utils_hexstr2bin (value); + if (!bytes) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid SSID '%s' (looks like hex SSID but isn't)", + value); + g_free (value); + goto error; } + } else + bytes = g_bytes_new (value, value_len); - tmp = nm_utils_hexstr2bin (value + 2, value_len - 2); - ssid_len = (value_len - 2) / 2; - memcpy (buf, tmp, ssid_len); - p = &buf[0]; - g_free (tmp); - } - + ssid_len = g_bytes_get_size (bytes); if (ssid_len > 32 || ssid_len == 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", value, ssid_len); + g_bytes_unref (bytes); g_free (value); goto error; } - array = g_byte_array_sized_new (ssid_len); - g_byte_array_append (array, (const guint8 *) p, ssid_len); - g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, array, NULL); - g_byte_array_free (array, TRUE); + g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, bytes, NULL); + g_bytes_unref (bytes); g_free (value); } @@ -3659,11 +3314,13 @@ make_wireless_setting (shvarFile *ifcfg, if (!strcmp (lcase, "ad-hoc")) { mode = "adhoc"; + } else if (!strcmp (lcase, "ap")) { + mode = "ap"; } else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) { mode = "infrastructure"; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid mode '%s' (not 'Ad-Hoc', 'Managed', or 'Auto')", + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", lcase); g_free (lcase); goto error; @@ -3675,39 +3332,54 @@ make_wireless_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "BSSID", FALSE); if (value) { - GByteArray *bssid; - - bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); - if (!bssid) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Invalid BSSID '%s'", value); - g_free (value); - goto error; - } - - g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL); - g_byte_array_free (bssid, TRUE); + value = g_strstrip (value); + g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, value, NULL); g_free (value); } value = svGetValue (ifcfg, "CHANNEL", FALSE); if (value) { - long int chan; - errno = 0; - chan = strtol (value, NULL, 10); - if (errno || chan <= 0 || chan > 196) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + chan = nm_utils_ascii_str_to_int64 (value, 10, 1, 196, 0); + if (errno || (chan == 0)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid wireless channel '%s'", value); g_free (value); goto error; } g_object_set (s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL); + g_free (value); + } + + value = svGetValue (ifcfg, "BAND", FALSE); + if (value) { + if (!strcmp (value, "a")) { + if (chan && chan <= 14) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Band '%s' invalid for channel %u", value, (guint32) chan); + g_free (value); + goto error; + } + } else if (!strcmp (value, "bg")) { + if (chan && chan > 14) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Band '%s' invalid for channel %u", value, (guint32) chan); + g_free (value); + goto error; + } + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid wireless band '%s'", value); + g_free (value); + goto error; + } + g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL); + g_free (value); + } else if (chan > 0) { if (chan > 14) g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL); else g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL); - g_free (value); } value = svGetValue (ifcfg, "MTU", FALSE); @@ -3717,7 +3389,7 @@ make_wireless_setting (shvarFile *ifcfg, errno = 0; mtu = strtol (value, NULL, 10); if (errno || mtu < 0 || mtu > 50000) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid wireless MTU '%s'", value); g_free (value); goto error; @@ -3748,7 +3420,7 @@ wireless_connection_from_ifcfg (const char *file, NMSetting *con_setting = NULL; NMSetting *wireless_setting = NULL; NMSetting8021x *s_8021x = NULL; - const GByteArray *ssid; + GBytes *ssid; NMSetting *security_setting = NULL; char *printable_ssid = NULL; const char *mode; @@ -3759,7 +3431,7 @@ wireless_connection_from_ifcfg (const char *file, g_return_val_if_fail (error != NULL, NULL); g_return_val_if_fail (*error == NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Wireless */ wireless_setting = make_wireless_setting (ifcfg, error); @@ -3770,9 +3442,10 @@ wireless_connection_from_ifcfg (const char *file, nm_connection_add_setting (connection, wireless_setting); ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting)); - if (ssid) - printable_ssid = nm_utils_ssid_to_utf8 (ssid); - else + if (ssid) { + printable_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + } else printable_ssid = g_strdup_printf ("unmanaged"); mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); @@ -3798,18 +3471,13 @@ wireless_connection_from_ifcfg (const char *file, printable_ssid, NULL); g_free (printable_ssid); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; } nm_connection_add_setting (connection, con_setting); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -3822,8 +3490,6 @@ make_wired_setting (shvarFile *ifcfg, NMSettingWired *s_wired; char *value = NULL; int mtu; - GByteArray *mac = NULL; - GSList *macaddr_blacklist = NULL; char *nettype; s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); @@ -3840,14 +3506,11 @@ make_wired_setting (shvarFile *ifcfg, g_free (value); } - if (read_mac_address (ifcfg, "HWADDR", ARPHRD_ETHER, &mac, error)) { - if (mac) { - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } - } else { - g_object_unref (s_wired); - return NULL; + value = svGetValue (ifcfg, "HWADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, value, NULL); + g_free (value); } value = svGetValue (ifcfg, "SUBCHANNELS", FALSE); @@ -3874,17 +3537,8 @@ make_wired_setting (shvarFile *ifcfg, if (num_chans < 2 || num_chans > 3) { PARSE_WARNING ("invalid SUBCHANNELS '%s' (%d channels, 2 or 3 expected)", value, g_strv_length (chans)); - } else { - GPtrArray *array = g_ptr_array_sized_new (num_chans); - - g_ptr_array_add (array, chans[0]); - g_ptr_array_add (array, chans[1]); - if (num_chans == 3) - g_ptr_array_add (array, chans[2]); - - g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, array, NULL); - g_ptr_array_free (array, TRUE); - } + } else + g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, chans, NULL); g_strfreev (chans); } g_free (value); @@ -3931,39 +3585,21 @@ make_wired_setting (shvarFile *ifcfg, } g_free (value); - mac = NULL; - if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &mac, error)) { - if (mac) { - g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } - } else { - PARSE_WARNING ("%s", (*error)->message); - g_clear_error (error); + value = svGetValue (ifcfg, "MACADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, value, NULL); + g_free (value); } value = svGetValue (ifcfg, "HWADDR_BLACKLIST", FALSE); if (value) { - char **list = NULL, **iter; - struct ether_addr addr; + char **strv; - list = g_strsplit_set (value, " \t", 0); - for (iter = list; iter && *iter; iter++) { - if (**iter == '\0') - continue; - if (!ether_aton_r (*iter, &addr)) { - PARSE_WARNING ("invalid MAC in HWADDR_BLACKLIST '%s'", *iter); - continue; - } - macaddr_blacklist = g_slist_prepend (macaddr_blacklist, *iter); - } - if (macaddr_blacklist) { - macaddr_blacklist = g_slist_reverse (macaddr_blacklist); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, macaddr_blacklist, NULL); - g_slist_free (macaddr_blacklist); - } + strv = transform_hwaddr_blacklist (value); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, strv, NULL); + g_strfreev (strv); g_free (value); - g_strfreev (list); } value = svGetValue (ifcfg, "KEY_MGMT", FALSE); @@ -3973,7 +3609,7 @@ make_wired_setting (shvarFile *ifcfg, if (!*s_8021x) goto error; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown wired KEY_MGMT type '%s'", value); goto error; } @@ -4001,11 +3637,11 @@ wired_connection_from_ifcfg (const char *file, g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL, NULL); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; @@ -4024,11 +3660,6 @@ wired_connection_from_ifcfg (const char *file, if (s_8021x) nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -4091,7 +3722,7 @@ parse_infiniband_p_key (shvarFile *ifcfg, g_free (ifname); if (!ret) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create InfiniBand setting."); } return ret; @@ -4105,7 +3736,6 @@ make_infiniband_setting (shvarFile *ifcfg, { NMSettingInfiniband *s_infiniband; char *value = NULL; - GByteArray *mac = NULL; int mtu; s_infiniband = NM_SETTING_INFINIBAND (nm_setting_infiniband_new ()); @@ -4122,14 +3752,11 @@ make_infiniband_setting (shvarFile *ifcfg, g_free (value); } - if (read_mac_address (ifcfg, "HWADDR", ARPHRD_INFINIBAND, &mac, error)) { - if (mac) { - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } - } else { - g_object_unref (s_infiniband); - return NULL; + value = svGetValue (ifcfg, "HWADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, value, NULL); + g_free (value); } if (svTrueValue (ifcfg, "CONNECTED_MODE", FALSE)) @@ -4167,11 +3794,11 @@ infiniband_connection_from_ifcfg (const char *file, g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_INFINIBAND_SETTING_NAME, NULL, NULL); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; @@ -4187,11 +3814,6 @@ infiniband_connection_from_ifcfg (const char *file, } nm_connection_add_setting (connection, infiniband_setting); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -4232,11 +3854,10 @@ make_bond_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "DEVICE", FALSE); if (!value || !strlen (value)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "mandatory DEVICE keyword missing"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); goto error; } - - g_object_set (s_bond, NM_SETTING_BOND_INTERFACE_NAME, value, NULL); g_free (value); value = svGetValue (ifcfg, "BONDING_OPTS", FALSE); @@ -4284,11 +3905,11 @@ bond_connection_from_ifcfg (const char *file, g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BOND_SETTING_NAME, NULL, _("Bond")); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; @@ -4312,11 +3933,6 @@ bond_connection_from_ifcfg (const char *file, if (s_8021x) nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -4338,7 +3954,8 @@ read_team_config (shvarFile *ifcfg, const char *key, GError **error) */ l = strlen (value); if (l > 20000) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "%s too long (size %zd)", key, l); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "%s too long (size %zd)", key, l); g_free (value); return NULL; } @@ -4359,11 +3976,10 @@ make_team_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "DEVICE", FALSE); if (!value || !strlen (value)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "mandatory DEVICE keyword missing"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); goto error; } - - g_object_set (s_team, NM_SETTING_TEAM_INTERFACE_NAME, value, NULL); g_free (value); value = read_team_config (ifcfg, "TEAM_CONFIG", &local_err); @@ -4395,11 +4011,11 @@ team_connection_from_ifcfg (const char *file, g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_TEAM_SETTING_NAME, NULL, _("Team")); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; @@ -4423,11 +4039,6 @@ team_connection_from_ifcfg (const char *file, if (s_8021x) nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -4511,27 +4122,22 @@ make_bridge_setting (shvarFile *ifcfg, guint32 u; gboolean stp = FALSE; gboolean stp_set = FALSE; - GByteArray *array = NULL; s_bridge = NM_SETTING_BRIDGE (nm_setting_bridge_new ()); value = svGetValue (ifcfg, "DEVICE", FALSE); if (!value || !strlen (value)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "mandatory DEVICE keyword missing"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "mandatory DEVICE keyword missing"); goto error; } - - g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, value, NULL); g_free (value); - if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &array, error)) { - if (array) { - g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, array, NULL); - g_byte_array_free (array, TRUE); - } - } else { - PARSE_WARNING ("%s", (*error)->message); - g_clear_error (error); + value = svGetValue (ifcfg, "MACADDR", FALSE); + if (value) { + value = g_strstrip (value); + g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, value, NULL); + g_free (value); } value = svGetValue (ifcfg, "STP", FALSE); @@ -4590,11 +4196,11 @@ bridge_connection_from_ifcfg (const char *file, g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_BRIDGE_SETTING_NAME, NULL, _("Bridge")); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); g_object_unref (connection); return NULL; @@ -4608,11 +4214,6 @@ bridge_connection_from_ifcfg (const char *file, } nm_connection_add_setting (connection, bridge_setting); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } - return connection; } @@ -4757,8 +4358,6 @@ parse_prio_map_list (NMSettingVlan *s_vlan, static NMSetting * make_vlan_setting (shvarFile *ifcfg, const char *file, - char **out_master, - NMSetting8021x **s_8021x, GError **error) { NMSettingVlan *s_vlan = NULL; @@ -4775,7 +4374,8 @@ make_vlan_setting (shvarFile *ifcfg, errno = 0; vlan_id = (gint) g_ascii_strtoll (value, NULL, 10); if (vlan_id < 0 || vlan_id > 4096 || errno) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid VLAN_ID '%s'", value); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid VLAN_ID '%s'", value); g_free (value); return NULL; } @@ -4785,7 +4385,7 @@ make_vlan_setting (shvarFile *ifcfg, /* Need DEVICE if we don't have a separate VLAN_ID property */ iface_name = svGetValue (ifcfg, "DEVICE", FALSE); if (!iface_name && vlan_id < 0) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing DEVICE property; cannot determine VLAN ID."); return NULL; } @@ -4796,8 +4396,6 @@ make_vlan_setting (shvarFile *ifcfg, parent = svGetValue (ifcfg, "PHYSDEV", FALSE); if (iface_name) { - g_object_set (s_vlan, NM_SETTING_VLAN_INTERFACE_NAME, iface_name, NULL); - p = strchr (iface_name, '.'); if (p) { /* eth0.43; PHYSDEV is assumed from it if unknown */ @@ -4813,7 +4411,7 @@ make_vlan_setting (shvarFile *ifcfg, } p++; } else { - /* format like vlan43; PHYSDEV or MASTER must be set */ + /* format like vlan43; PHYSDEV must be set */ if (g_str_has_prefix (iface_name, "vlan")) p = iface_name + 4; } @@ -4824,7 +4422,7 @@ make_vlan_setting (shvarFile *ifcfg, */ vlan_id = (gint) g_ascii_strtoll (p, &end, 10); if (vlan_id < 0 || vlan_id > 4095 || end == p || *end) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to determine VLAN ID from DEVICE '%s'", iface_name); goto error; @@ -4833,14 +4431,14 @@ make_vlan_setting (shvarFile *ifcfg, } if (vlan_id < 0) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to determine VLAN ID from DEVICE or VLAN_ID."); goto error; } g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); if (parent == NULL) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to determine VLAN parent from DEVICE or PHYSDEV"); goto error; } @@ -4863,8 +4461,6 @@ make_vlan_setting (shvarFile *ifcfg, parse_prio_map_list (s_vlan, ifcfg, "VLAN_INGRESS_PRIORITY_MAP", NM_VLAN_INGRESS_MAP); parse_prio_map_list (s_vlan, ifcfg, "VLAN_EGRESS_PRIORITY_MAP", NM_VLAN_EGRESS_MAP); - if (out_master) - *out_master = svGetValue (ifcfg, "MASTER", FALSE); return (NMSetting *) s_vlan; error: @@ -4884,38 +4480,30 @@ vlan_connection_from_ifcfg (const char *file, NMSetting *wired_setting = NULL; NMSetting *vlan_setting = NULL; NMSetting8021x *s_8021x = NULL; - char *master = NULL; g_return_val_if_fail (file != NULL, NULL); g_return_val_if_fail (ifcfg != NULL, NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); con_setting = make_connection_setting (file, ifcfg, NM_SETTING_VLAN_SETTING_NAME, NULL, "Vlan"); if (!con_setting) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Failed to create connection setting."); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Failed to create connection setting."); g_object_unref (connection); return NULL; } + check_if_bond_slave (ifcfg, NM_SETTING_CONNECTION (con_setting)); + check_if_team_slave (ifcfg, NM_SETTING_CONNECTION (con_setting)); nm_connection_add_setting (connection, con_setting); - vlan_setting = make_vlan_setting (ifcfg, file, &master, &s_8021x, error); + vlan_setting = make_vlan_setting (ifcfg, file, error); if (!vlan_setting) { g_object_unref (connection); return NULL; } nm_connection_add_setting (connection, vlan_setting); - /* Handle master interface or connection */ - if (master) { - g_object_set (con_setting, NM_SETTING_CONNECTION_MASTER, master, NULL); - g_object_set (con_setting, - NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_VLAN_SETTING_NAME, - NULL); - g_free (master); - } - wired_setting = make_wired_setting (ifcfg, file, &s_8021x, error); if (!wired_setting) { g_object_unref (connection); @@ -4925,10 +4513,6 @@ vlan_connection_from_ifcfg (const char *file, if (s_8021x) nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - if (!nm_connection_verify (connection, error)) { - g_object_unref (connection); - return NULL; - } return connection; } @@ -4943,7 +4527,7 @@ create_unhandled_connection (const char *filename, shvarFile *ifcfg, g_assert (out_spec != NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Get NAME, UUID, etc. We need to set a connection type (generic) and add * an empty type-specific setting as well, to make sure it passes @@ -5004,7 +4588,7 @@ uuid_from_file (const char *filename) uuid = svGetValue (ifcfg, "UUID", FALSE); if (!uuid || !strlen (uuid)) { g_free (uuid); - uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); } svCloseFile (ifcfg); @@ -5020,7 +4604,7 @@ check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) /* If there is no IPv4 config or it doesn't contain DNS searches, * read DOMAIN and put the domains into IPv6. */ - if (!s_ip4 || nm_setting_ip4_config_get_num_dns_searches (NM_SETTING_IP4_CONFIG (s_ip4)) == 0) { + if (!s_ip4 || nm_setting_ip_config_get_num_dns_searches (NM_SETTING_IP_CONFIG (s_ip4)) == 0) { /* DNS searches */ char *value = svGetValue (ifcfg, "DOMAIN", FALSE); if (value) { @@ -5029,7 +4613,7 @@ check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) char **item; for (item = searches; *item; item++) { if (strlen (*item)) { - if (!nm_setting_ip6_config_add_dns_search (NM_SETTING_IP6_CONFIG (s_ip6), *item)) + if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item)) PARSE_WARNING ("duplicate DNS domain '%s'", *item); } } @@ -5044,7 +4628,6 @@ NMConnection * connection_from_file (const char *filename, const char *network_file, /* for unit tests only */ const char *test_type, /* for unit tests only */ - const char *iscsiadm_path, /* for unit tests only */ char **out_unhandled, char **out_keyfile, char **out_routefile, @@ -5072,12 +4655,9 @@ connection_from_file (const char *filename, if (!network_file) network_file = SYSCONFDIR "/sysconfig/network"; - if (!iscsiadm_path) - iscsiadm_path = "/sbin/iscsiadm"; - ifcfg_name = utils_get_ifcfg_name (filename, TRUE); if (!ifcfg_name) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring connection '%s' because it's not an ifcfg file.", filename); return NULL; } @@ -5095,6 +4675,17 @@ connection_from_file (const char *filename, goto done; } + /* iBFT is handled by the iBFT settings plugin */ + bootproto = svGetValue (parsed, "BOOTPROTO", FALSE); + if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) { + if (out_ignore_error) + *out_ignore_error = TRUE; + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring iBFT configuration"); + g_free (bootproto); + goto done; + } + type = NULL; devtype = svGetValue (parsed, "DEVICETYPE", FALSE); @@ -5114,7 +4705,7 @@ connection_from_file (const char *filename, device = svGetValue (parsed, "DEVICE", FALSE); if (!device) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "File '%s' had neither TYPE nor DEVICE keys.", filename); goto done; } @@ -5122,7 +4713,7 @@ connection_from_file (const char *filename, if (!strcmp (device, "lo")) { if (out_ignore_error) *out_ignore_error = TRUE; - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring loopback device config."); g_free (device); goto done; @@ -5156,7 +4747,7 @@ connection_from_file (const char *filename, if (svTrueValue (parsed, "BONDING_MASTER", FALSE) && strcasecmp (type, TYPE_BOND)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "BONDING_MASTER=yes key only allowed in TYPE=bond connections"); goto done; } @@ -5189,7 +4780,7 @@ connection_from_file (const char *filename, if (!connection) goto done; - s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, error); + s_ip6 = make_ip6_setting (parsed, network_file, error); if (!s_ip6) { g_object_unref (connection); connection = NULL; @@ -5197,13 +4788,13 @@ connection_from_file (const char *filename, } else nm_connection_add_setting (connection, s_ip6); - s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, error); + s_ip4 = make_ip4_setting (parsed, network_file, error); if (!s_ip4) { g_object_unref (connection); connection = NULL; goto done; } else { - read_aliases (NM_SETTING_IP4_CONFIG (s_ip4), filename, network_file); + read_aliases (NM_SETTING_IP_CONFIG (s_ip4), filename, network_file); nm_connection_add_setting (connection, s_ip4); } @@ -5231,25 +4822,7 @@ connection_from_file (const char *filename, if (s_dcb) nm_connection_add_setting (connection, s_dcb); - /* iSCSI / ibft connections are read-only since their settings are - * stored in NVRAM and can only be changed in BIOS. - */ - bootproto = svGetValue (parsed, "BOOTPROTO", FALSE); - if ( bootproto - && connection - && !g_ascii_strcasecmp (bootproto, "ibft")) { - NMSettingConnection *s_con; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL); - } - g_free (bootproto); - - nm_utils_normalize_connection (connection, TRUE); - - if (!nm_connection_verify (connection, error)) { + if (!nm_connection_normalize (connection, NULL, NULL, error)) { g_object_unref (connection); connection = NULL; } diff --git a/src/settings/plugins/ifcfg-rh/reader.h b/src/settings/plugins/ifcfg-rh/reader.h index 371f4504..c23e5870 100644 --- a/src/settings/plugins/ifcfg-rh/reader.h +++ b/src/settings/plugins/ifcfg-rh/reader.h @@ -29,7 +29,6 @@ NMConnection *connection_from_file (const char *filename, const char *network_file, /* for unit tests only */ const char *test_type, /* for unit tests only */ - const char *iscsiadm_path, /* for unit tests only */ char **out_unhandled, char **out_keyfile, char **out_routefile, diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 4e8e29ce..6c9769b2 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -23,6 +23,8 @@ * */ +#include "config.h" + #include #include #include @@ -34,6 +36,11 @@ #include "shvar.h" +#include "NetworkManagerUtils.h" +#include "nm-logging.h" + +#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) + /* Open the file , 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. @@ -233,8 +240,7 @@ svEscape (const char *s) new[j++] = s[i]; } new[j++] = '"'; - new[j++] = '\0' -; + new[j++] = '\0'; g_assert (j == slen + mangle - newline + 3); return new; @@ -261,7 +267,8 @@ svGetValue (shvarFile *s, const char *key, gboolean verbatim) for (s->current = s->lineList; s->current; s->current = s->current->next) { line = s->current->data; if (!strncmp (keyString, line, len)) { - value = g_strdup (line + len); + /* Strip trailing spaces before unescaping to preserve spaces quoted whitespace */ + value = g_strchomp (g_strdup (line + len)); if (!verbatim) svUnescape (value); break; @@ -306,6 +313,38 @@ svTrueValue (shvarFile *s, const char *key, gboolean def) return returnValue; } +/* svGetValueInt64: + * @s: fhe file + * @key: the name of the key to read + * @base: the numeric base (usually 10). Setting to 0 means "auto". Usually you want 10. + * @min: the minimum for range-check + * @max: the maximum for range-check + * @fallback: the fallback value in any error case + * + * Reads a value @key and converts it to an integer using nm_utils_ascii_str_to_int64(). + * In case of error, @errno will be set and @fallback returned. */ +gint64 +svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback) +{ + char *tmp; + gint64 result; + int errsv; + + tmp = svGetValue (s, key, FALSE); + if (!tmp) { + errno = 0; + return fallback; + } + + 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); + + return result; +} /* Set the variable equal to the value . * If does not exist, and the pointer is set, append diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 4cbf1a31..b2a2f263 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -63,6 +63,8 @@ char *svGetValue (shvarFile *s, const char *key, gboolean verbatim); */ gboolean svTrueValue (shvarFile *s, const char *key, gboolean def); +gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); + /* Set the variable equal to the value . * If does not exist, and the pointer is set, append * the key=value pair after that line. Otherwise, prepend the pair diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am index e758776d..5a17ed9b 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am @@ -6,20 +6,16 @@ SUBDIRS=network-scripts AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ $(CODE_COVERAGE_CFLAGS) \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src/ \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/settings \ - -I$(top_srcdir)/src/posix-signals \ -I$(srcdir)/../ \ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-rh"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" \ @@ -31,15 +27,10 @@ AM_LDFLAGS = \ $(DBUS_LIBS) \ $(CODE_COVERAGE_LDFLAGS) -AM_LDADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la - noinst_PROGRAMS = test-ifcfg-rh test-ifcfg-rh-utils test_ifcfg_rh_SOURCES = \ test-ifcfg-rh.c \ - ../errors.c \ ../reader.c \ ../shvar.c \ ../utils.c \ @@ -54,19 +45,9 @@ test_ifcfg_rh_utils_SOURCES = \ ../shvar.c test_ifcfg_rh_utils_LDADD = \ - $(AM_LDADD) + $(top_builddir)/src/libNetworkManager.la TESTS = test-ifcfg-rh-utils test-ifcfg-rh -EXTRA_DIST = \ - iscsiadm-test-dhcp \ - iscsiadm-test-static \ - iscsiadm-test-bad-ipaddr \ - iscsiadm-test-bad-gateway \ - iscsiadm-test-bad-dns1 \ - iscsiadm-test-bad-dns2 \ - iscsiadm-test-bad-entry \ - iscsiadm-test-bad-record - endif diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in index 2018134a..f34e759d 100644 --- a/src/settings/plugins/ifcfg-rh/tests/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in @@ -106,12 +106,11 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am__test_ifcfg_rh_SOURCES_DIST = test-ifcfg-rh.c ../errors.c \ - ../reader.c ../shvar.c ../utils.c ../writer.c +am__test_ifcfg_rh_SOURCES_DIST = test-ifcfg-rh.c ../reader.c \ + ../shvar.c ../utils.c ../writer.c @ENABLE_TESTS_TRUE@am_test_ifcfg_rh_OBJECTS = test-ifcfg-rh.$(OBJEXT) \ -@ENABLE_TESTS_TRUE@ errors.$(OBJEXT) reader.$(OBJEXT) \ -@ENABLE_TESTS_TRUE@ shvar.$(OBJEXT) utils.$(OBJEXT) \ -@ENABLE_TESTS_TRUE@ writer.$(OBJEXT) +@ENABLE_TESTS_TRUE@ reader.$(OBJEXT) shvar.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ utils.$(OBJEXT) writer.$(OBJEXT) test_ifcfg_rh_OBJECTS = $(am_test_ifcfg_rh_OBJECTS) @ENABLE_TESTS_TRUE@test_ifcfg_rh_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la @@ -125,7 +124,8 @@ am__test_ifcfg_rh_utils_SOURCES_DIST = test-ifcfg-rh-utils.c \ @ENABLE_TESTS_TRUE@ test-ifcfg-rh-utils.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ utils.$(OBJEXT) shvar.$(OBJEXT) test_ifcfg_rh_utils_OBJECTS = $(am_test_ifcfg_rh_utils_OBJECTS) -@ENABLE_TESTS_TRUE@test_ifcfg_rh_utils_DEPENDENCIES = $(AM_LDADD) +@ENABLE_TESTS_TRUE@test_ifcfg_rh_utils_DEPENDENCIES = \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -261,6 +261,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -384,6 +386,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -403,6 +406,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -429,7 +433,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -511,20 +515,16 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@SUBDIRS = network-scripts @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_CFLAGS) \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/ \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/logging \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/platform \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/posix-signals \ @ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ @ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-rh"\" \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \ @ENABLE_TESTS_TRUE@ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\" \ @@ -536,13 +536,8 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_LDFLAGS) -@ENABLE_TESTS_TRUE@AM_LDADD = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la - @ENABLE_TESTS_TRUE@test_ifcfg_rh_SOURCES = \ @ENABLE_TESTS_TRUE@ test-ifcfg-rh.c \ -@ENABLE_TESTS_TRUE@ ../errors.c \ @ENABLE_TESTS_TRUE@ ../reader.c \ @ENABLE_TESTS_TRUE@ ../shvar.c \ @ENABLE_TESTS_TRUE@ ../utils.c \ @@ -557,17 +552,7 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ ../shvar.c @ENABLE_TESTS_TRUE@test_ifcfg_rh_utils_LDADD = \ -@ENABLE_TESTS_TRUE@ $(AM_LDADD) - -@ENABLE_TESTS_TRUE@EXTRA_DIST = \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-dhcp \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-static \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-ipaddr \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-gateway \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-dns1 \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-dns2 \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-entry \ -@ENABLE_TESTS_TRUE@ iscsiadm-test-bad-record +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la all: all-recursive @@ -627,7 +612,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shvar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ifcfg-rh-utils.Po@am__quote@ @@ -656,20 +640,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -errors.o: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.o -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c - -errors.obj: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.obj -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` - reader.o: ../reader.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reader.o -MD -MP -MF $(DEPDIR)/reader.Tpo -c -o reader.o `test -f '../reader.c' || echo '$(srcdir)/'`../reader.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reader.Tpo $(DEPDIR)/reader.Po diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 deleted file mode 100755 index 4a6a9382..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress = 192.168.32.72 -iface.subnet_mask = 255.255.252.0 -iface.gateway = 192.168.35.254 -iface.primary_dns = 10000.500.250.1 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 deleted file mode 100755 index 9bd5839b..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress = 192.168.32.72 -iface.subnet_mask = 255.255.252.0 -iface.gateway = 192.168.35.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = blah.foo.bar.baz -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry deleted file mode 100755 index eba0ec67..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress 192.168.32.72 -iface.subnet_mask = 255.255.252.0 -iface.gateway = 192.168.35.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f1 -iface.bootproto = DHCP -iface.gateway = 10.16.52.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth1 -node.name = iqn.1.2008-11.com.blahblah:iscsi1 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway deleted file mode 100755 index b3dc7447..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress = aa.bb.cc.dd -iface.subnet_mask = 255.255.252.0 -iface.gateway = 192.168.35.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr deleted file mode 100755 index 92f44777..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress = 192.168.32.72 -iface.subnet_mask = 255.255.252.0 -iface.gateway = bb.cc.dd.ee -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record deleted file mode 100755 index a2d215fe..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = DHCP -iface.gateway = 10.16.52.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp deleted file mode 100755 index 6de0637c..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = DHCP -iface.gateway = 10.16.52.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f1 -iface.bootproto = DHCP -iface.gateway = 10.16.52.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth1 -node.name = iqn.1.2008-11.com.blahblah:iscsi1 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static deleted file mode 100755 index 99a6e7c1..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -cat << EOF -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f0 -iface.bootproto = STATIC -iface.ipaddress = 192.168.32.72 -iface.subnet_mask = 255.255.252.0 -iface.gateway = 192.168.35.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth0 -node.name = iqn.0.2008-11.com.blahblah:iscsi0 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -# BEGIN RECORD -iface.initiatorname = iqn.pjones6 -iface.hwaddress = 00:33:21:98:b9:f1 -iface.bootproto = DHCP -iface.gateway = 10.16.52.254 -iface.primary_dns = 10.16.255.2 -iface.secondary_dns = 10.16.255.3 -iface.vlan = 0 -iface.net_ifacename = eth1 -node.name = iqn.1.2008-11.com.blahblah:iscsi1 -node.conn[0].address = 10.16.52.16 -node.conn[0].port = 3260 -node.boot_lun = 00000000 -# END RECORD -EOF - diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 1701aeeb..8941da3a 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -1,5 +1,6 @@ EXTRA_DIST = \ ifcfg-test-minimal \ + ifcfg-test-misc-variables \ ifcfg-test-variables-corner-cases-1 \ ifcfg-test-nm-controlled \ ifcfg-test-nm-controlled-unrecognized \ @@ -59,10 +60,12 @@ EXTRA_DIST = \ ifcfg-test-wifi-wpa-eap-ttls-tls \ keys-test-wifi-wpa-eap-ttls-tls \ ifcfg-test-wifi-hidden \ + ifcfg-test-wifi-band-a \ + ifcfg-test-wifi-band-a-channel-mismatch \ + ifcfg-test-wifi-band-bg-channel-mismatch \ test_ca_cert.pem \ test1_key_and_cert.pem \ - ifcfg-test-ibft-dhcp \ - ifcfg-test-ibft-static \ + ifcfg-test-ibft \ ifcfg-test-static-routes-legacy \ route-test-static-routes-legacy \ ifcfg-test-wired-static-routes \ @@ -116,7 +119,8 @@ EXTRA_DIST = \ ifcfg-test-fcoe-vn2vn \ ifcfg-test-team-master \ ifcfg-test-team-port \ - ifcfg-test-team-port-empty-config + ifcfg-test-team-port-empty-config \ + ifcfg-test-vlan-trailing-spaces # make target dependencies can't have colons in their names, which ends up # meaning that we can't add the alias files to EXTRA_DIST diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in index eff763e8..aac646f8 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in @@ -129,6 +129,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -252,6 +254,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -271,6 +274,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -297,7 +301,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -378,6 +382,7 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ EXTRA_DIST = \ ifcfg-test-minimal \ + ifcfg-test-misc-variables \ ifcfg-test-variables-corner-cases-1 \ ifcfg-test-nm-controlled \ ifcfg-test-nm-controlled-unrecognized \ @@ -437,10 +442,12 @@ EXTRA_DIST = \ ifcfg-test-wifi-wpa-eap-ttls-tls \ keys-test-wifi-wpa-eap-ttls-tls \ ifcfg-test-wifi-hidden \ + ifcfg-test-wifi-band-a \ + ifcfg-test-wifi-band-a-channel-mismatch \ + ifcfg-test-wifi-band-bg-channel-mismatch \ test_ca_cert.pem \ test1_key_and_cert.pem \ - ifcfg-test-ibft-dhcp \ - ifcfg-test-ibft-static \ + ifcfg-test-ibft \ ifcfg-test-static-routes-legacy \ route-test-static-routes-legacy \ ifcfg-test-wired-static-routes \ @@ -494,7 +501,8 @@ EXTRA_DIST = \ ifcfg-test-fcoe-vn2vn \ ifcfg-test-team-master \ ifcfg-test-team-port \ - ifcfg-test-team-port-empty-config + ifcfg-test-team-port-empty-config \ + ifcfg-test-vlan-trailing-spaces # make target dependencies can't have colons in their names, which ends up diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft new file mode 100644 index 00000000..d3e4edca --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft @@ -0,0 +1,10 @@ +# Generated by dracut initrd +DEVICE="ibft0" +ONBOOT=yes +NETBOOT=yes +UUID="2aa8c19d-9744-4ca4-b74f-c37e73f2918e" +BOOTPROTO=ibft +HWADDR="00:33:21:98:b9:f0" +TYPE=Ethernet +NAME="ibft0" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp deleted file mode 100644 index abfcd6e4..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp +++ /dev/null @@ -1,4 +0,0 @@ -# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) -DEVICE=eth0 -HWADDR=00:33:21:98:b9:f1 -BOOTPROTO=ibft diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static deleted file mode 100644 index 99b02e42..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static +++ /dev/null @@ -1,4 +0,0 @@ -# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) -DEVICE=eth0 -HWADDR=00:33:21:98:b9:f0 -BOOTPROTO=ibft diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-misc-variables b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-misc-variables new file mode 100644 index 00000000..c7892a21 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-misc-variables @@ -0,0 +1,3 @@ +DEVICE=eth0 +HWADDR_BLACKLIST="00:16:41:11:22:88 00:16:41:11:22:99 XX:aa:invalid 6A:5D:5A:FA:DD:F0" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-trailing-spaces b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-trailing-spaces new file mode 100644 index 00000000..4a31e475 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-trailing-spaces @@ -0,0 +1,11 @@ +DEVICE="vlan201" +ONBOOT=yes +NETBOOT=yes +BOOTPROTO=none +IPADDR="10.130.70.7" +NETMASK="255.255.0.0" +TYPE=Vlan +NAME="vlan201" +VLAN=yes +PHYSDEV="enccw0.0.fb00" + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a new file mode 100644 index 00000000..43286111 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a @@ -0,0 +1,13 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +NM_CONTROLLED=yes +BOOTPROTO=dhcp +ESSID=blahblah +BAND=a +MODE=Managed +RATE=auto +ONBOOT=yes +USERCTL=yes +PEERDNS=yes +IPV6INIT=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch new file mode 100644 index 00000000..8905ba0b --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch @@ -0,0 +1,9 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=9 +BAND=a +MODE=Managed + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch new file mode 100644 index 00000000..e02e21ad --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch @@ -0,0 +1,9 @@ +TYPE=Wireless +DEVICE=eth2 +HWADDR=00:16:41:11:22:33 +BOOTPROTO=dhcp +ESSID=blahblah +CHANNEL=183 +BAND=bg +MODE=Managed + diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open index d4bb8f75..48db45b2 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open @@ -3,6 +3,7 @@ DEVICE=eth2 HWADDR=00:16:41:11:22:33 NM_CONTROLLED=yes BOOTPROTO=dhcp +AUTOCONNECT_PRIORITY=-1 ESSID=blahblah CHANNEL=1 MODE=Managed 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 39c81027..d82a3270 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 @@ -18,6 +18,8 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include 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 c1b14f12..4a6940d0 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -18,12 +18,12 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include -#include -#include #include #include #include @@ -46,7 +46,7 @@ #include #include #include -#include +#include "nm-core-internal.h" #include "NetworkManagerUtils.h" @@ -185,17 +185,17 @@ test_read_basic (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_id = "System test-minimal"; guint64 expected_timestamp = 0; gboolean success; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-minimal", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -220,22 +220,71 @@ test_read_basic (void) g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, &expected_mac_address[0], ETH_ALEN) == 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); /* ===== IPv4 SETTING ===== */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); /* ===== IPv6 SETTING ===== */ s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - g_assert (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); + + g_object_unref (connection); +} + +static void +test_read_miscellaneous_variables (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + GError *error = NULL; + char *expected_mac_blacklist[3] = { "00:16:41:11:22:88", "00:16:41:11:22:99", "6a:5d:5a:fa:dd:f0" }; + int mac_blacklist_num, i; + guint64 expected_timestamp = 0; + gboolean success; + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*invalid MAC in HWADDR_BLACKLIST 'XX:aa:invalid'*"); + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-misc-variables", + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + g_test_assert_expected_messages (); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* ===== CONNECTION SETTING ===== */ + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpint (nm_setting_connection_get_timestamp (s_con), ==, expected_timestamp); + g_assert (nm_setting_connection_get_autoconnect (s_con)); + + /* ===== WIRED SETTING ===== */ + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); + + /* MAC blacklist */ + mac_blacklist_num = nm_setting_wired_get_num_mac_blacklist_items (s_wired); + g_assert_cmpint (mac_blacklist_num, ==, 3); + for (i = 0; i < mac_blacklist_num; i++) + g_assert (nm_utils_hwaddr_matches (nm_setting_wired_get_mac_blacklist_item (s_wired, i), -1, expected_mac_blacklist[i], -1)); + + /* ===== IPv4 SETTING ===== */ + s_ip4 = nm_connection_get_setting_ip4_config (connection); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); g_object_unref (connection); } @@ -246,9 +295,9 @@ test_read_variables_corner_cases (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_zone = "'"; const char *expected_id = "\""; @@ -256,7 +305,7 @@ test_read_variables_corner_cases (void) gboolean success; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-variables-corner-cases-1", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -277,16 +326,15 @@ test_read_variables_corner_cases (void) g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 0); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, &expected_mac_address[0], ETH_ALEN) == 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); /* ===== IPv4 SETTING ===== */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); g_object_unref (connection); } @@ -303,7 +351,7 @@ test_read_unmanaged (void) gboolean success; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled", - NULL, TYPE_ETHERNET, NULL, + NULL, TYPE_ETHERNET, &unhandled_spec, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); @@ -336,7 +384,7 @@ test_read_unmanaged_unrecognized (void) gboolean success; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-nm-controlled-unrecognized", - NULL, NULL, NULL, + NULL, NULL, &unhandled_spec, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); @@ -367,7 +415,7 @@ test_read_unrecognized (void) gboolean success; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-unrecognized", - NULL, NULL, NULL, + NULL, NULL, &unhandled_spec, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); @@ -394,27 +442,17 @@ test_read_wired_static (const char *file, NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; - const char *expected_dns1 = "4.2.2.1"; - const char *expected_dns2 = "4.2.2.2"; - guint32 addr; - struct in6_addr addr6; - const char *expected_address1 = "192.168.1.5"; - const char *expected_address1_gw = "192.168.1.1"; - const char *expected6_address1 = "dead:beaf::1"; - const char *expected6_address2 = "dead:beaf::2"; - const char *expected6_dns1 = "1:2:3:4::a"; - const char *expected6_dns2 = "1:2:3:4::b"; - NMIP4Address *ip4_addr; - NMIP6Address *ip6_addr; + NMIPAddress *ip4_addr; + NMIPAddress *ip6_addr; gboolean success; - connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, + connection = connection_from_file (file, NULL, TYPE_ETHERNET, &unmanaged, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -436,64 +474,57 @@ test_read_wired_static (const char *file, g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1492); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, &expected_mac_address[0], ETH_ALEN) == 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); /* ===== IPv4 SETTING ===== */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert (nm_setting_ip4_config_get_may_fail (s_ip4)); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip4_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpint (inet_pton (AF_INET, expected_dns1, &addr), >, 0); - g_assert_cmpint (nm_setting_ip4_config_get_dns (s_ip4, 0), ==, addr); - g_assert_cmpint (inet_pton (AF_INET, expected_dns2, &addr), >, 0); - g_assert_cmpint (nm_setting_ip4_config_get_dns (s_ip4, 1), ==, addr); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); /* IP addresses */ - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); g_assert (ip4_addr); - g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpint (inet_pton (AF_INET, expected_address1, &addr), >, 0); - g_assert_cmpint (nm_ip4_address_get_address (ip4_addr), ==, addr); - g_assert_cmpint (inet_pton (AF_INET, expected_address1_gw, &addr), >, 0); - g_assert_cmpint (nm_ip4_address_get_gateway (ip4_addr), ==, addr); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); + + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); /* ===== IPv6 SETTING ===== */ s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); if (expect_ip6) { - g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); - g_assert (nm_setting_ip6_config_get_may_fail (s_ip6)); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_MANUAL); + g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip6_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpint (inet_pton (AF_INET6, expected6_dns1, &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6)); - g_assert_cmpint (inet_pton (AF_INET6, expected6_dns2, &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6)); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1:2:3:4::b"); /* IP addresses */ - g_assert_cmpint (nm_setting_ip6_config_get_num_addresses (s_ip6), ==, 2); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 2); - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); g_assert (ip6_addr); - g_assert_cmpint (nm_ip6_address_get_prefix (ip6_addr), ==, 64); - g_assert_cmpint (inet_pton (AF_INET6, expected6_address1, &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6)); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "dead:beaf::1"); - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); g_assert (ip6_addr); - g_assert_cmpint (nm_ip6_address_get_prefix (ip6_addr), ==, 56); - g_assert_cmpint (inet_pton (AF_INET6, expected6_address2, &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6)); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "dead:beaf::2"); } else { - g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); } g_free (unmanaged); @@ -506,9 +537,9 @@ test_read_wired_static_no_prefix (gconstpointer user_data) guint32 expected_prefix = GPOINTER_TO_UINT (user_data); NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; GError *error = NULL; - NMIP4Address *ip4_addr; + NMIPAddress *ip4_addr; char *file, *expected_id; file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-wired-static-no-prefix-%u", expected_prefix); @@ -516,7 +547,7 @@ test_read_wired_static_no_prefix (gconstpointer user_data) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing PREFIX, assuming*"); - connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, + connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); g_assert_no_error (error); @@ -531,12 +562,12 @@ test_read_wired_static_no_prefix (gconstpointer user_data) /* ===== IPv4 SETTING ===== */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 1); - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); g_assert (ip4_addr); - g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, expected_prefix); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, expected_prefix); g_free (file); g_free (expected_id); @@ -551,26 +582,22 @@ test_read_wired_dhcp (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee }; const char *tmp; const char *expected_id = "System test-wired-dhcp"; - const char *expected_dns1 = "4.2.2.1"; - const char *expected_dns2 = "4.2.2.2"; - guint32 addr; const char *expected_dhcp_hostname = "foobar"; connection = connection_from_file (TEST_IFCFG_WIRED_DHCP, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -630,18 +657,13 @@ test_read_wired_dhcp (void) NM_SETTING_WIRED_SETTING_NAME); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array != NULL, + mac = nm_setting_wired_get_mac_address (s_wired); + ASSERT (mac != NULL, "wired-dhcp-verify-wired", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_DHCP, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_WIRED_DHCP, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP, NM_SETTING_WIRED_SETTING_NAME, @@ -656,59 +678,49 @@ test_read_wired_dhcp (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - tmp = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); + tmp = nm_setting_ip_config_get_dhcp_hostname (s_ip4); ASSERT (tmp != NULL, "wired-dhcp-verify-ip4", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME); + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME); ASSERT (strcmp (tmp, expected_dhcp_hostname) == 0, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME); + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME); - ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE, + ASSERT (nm_setting_ip_config_get_ignore_auto_dns (s_ip4) == TRUE, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS); + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS); /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip4) == 2, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, - "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_IFCFG_WIRED_DHCP, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 0), "4.2.2.1") == 0, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, - "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_IFCFG_WIRED_DHCP, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 1), "4.2.2.2") == 0, "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", TEST_IFCFG_WIRED_DHCP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); g_free (unmanaged); g_free (keyfile); @@ -721,17 +733,15 @@ static void test_read_wired_dhcp_plus_ip (void) { NMConnection *connection; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; GError *error = NULL; - guint32 addr4; - struct in6_addr addr6; - NMIP4Address *ip4_addr; - NMIP6Address *ip6_addr; + NMIPAddress *ip4_addr; + NMIPAddress *ip6_addr; gboolean success; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL, NULL, + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -742,321 +752,132 @@ test_read_wired_dhcp_plus_ip (void) /* ===== IPv4 SETTING ===== */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip4_config_get_may_fail (s_ip4)); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert (nm_setting_ip_config_get_may_fail (s_ip4)); /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip4_config_get_num_dns (s_ip4), ==, 2); - g_assert_cmpint (inet_pton (AF_INET, "4.2.2.1", &addr4), >, 0); - g_assert_cmpint (nm_setting_ip4_config_get_dns (s_ip4, 0), ==, addr4); - g_assert_cmpint (inet_pton (AF_INET, "4.2.2.2", &addr4), >, 0); - g_assert_cmpint (nm_setting_ip4_config_get_dns (s_ip4, 1), ==, addr4); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 0), ==, "4.2.2.1"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip4, 1), ==, "4.2.2.2"); /* IP addresses */ - g_assert_cmpint (nm_setting_ip4_config_get_num_addresses (s_ip4), ==, 2); - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 2); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); g_assert (ip4_addr); - g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 24); - g_assert_cmpint (inet_pton (AF_INET, "1.2.3.4", &addr4), >, 0); - g_assert_cmpint (nm_ip4_address_get_address (ip4_addr), ==, addr4); - g_assert_cmpint (inet_pton (AF_INET, "1.1.1.1", &addr4), >, 0); - g_assert_cmpint (nm_ip4_address_get_gateway (ip4_addr), ==, addr4); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 1); + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); + + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 1); g_assert (ip4_addr); - g_assert_cmpint (nm_ip4_address_get_prefix (ip4_addr), ==, 16); - g_assert_cmpint (inet_pton (AF_INET, "9.8.7.6", &addr4), >, 0); - g_assert_cmpint (nm_ip4_address_get_address (ip4_addr), ==, addr4); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 16); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "9.8.7.6"); /* ===== IPv6 SETTING ===== */ s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); - g_assert (nm_setting_ip6_config_get_may_fail (s_ip6)); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert (nm_setting_ip_config_get_may_fail (s_ip6)); /* DNS Addresses */ - g_assert_cmpint (nm_setting_ip6_config_get_num_dns (s_ip6), ==, 2); - g_assert_cmpint (inet_pton (AF_INET6, "1:2:3:4::a", &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6)); - g_assert_cmpint (inet_pton (AF_INET6, "1:2:3:4::b", &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6)); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip6), ==, 2); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 0), ==, "1:2:3:4::a"); + g_assert_cmpstr (nm_setting_ip_config_get_dns (s_ip6, 1), ==, "1:2:3:4::b"); /* IP addresses */ - g_assert_cmpint (nm_setting_ip6_config_get_num_addresses (s_ip6), ==, 3); - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 3); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); g_assert (ip6_addr); - g_assert_cmpint (nm_ip6_address_get_prefix (ip6_addr), ==, 56); - g_assert_cmpint (inet_pton (AF_INET6, "1001:abba::1234", &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6)); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); g_assert (ip6_addr); - g_assert_cmpint (nm_ip6_address_get_prefix (ip6_addr), ==, 64); - g_assert_cmpint (inet_pton (AF_INET6, "2001:abba::2234", &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6)); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "2001:abba::2234"); - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 2); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 2); g_assert (ip6_addr); - g_assert_cmpint (nm_ip6_address_get_prefix (ip6_addr), ==, 96); - g_assert_cmpint (inet_pton (AF_INET6, "3001:abba::3234", &addr6), >, 0); - g_assert (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6)); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 96); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "3001:abba::3234"); g_object_unref (connection); } -#define TEST_IFCFG_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway" -#define TEST_NETWORK_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway" - static void test_read_wired_global_gateway (void) { NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; + NMSettingIPConfig *s_ip4; GError *error = NULL; - const char *tmp; - const char *expected_id = "System test-wired-global-gateway"; - guint32 addr; - const char *expected_address1 = "192.168.1.5"; - const char *expected_address1_gw = "192.168.1.2"; - NMIP4Address *ip4_addr; - - connection = connection_from_file (TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - TEST_NETWORK_WIRED_GLOBAL_GATEWAY, - TYPE_ETHERNET, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - ASSERT (connection != NULL, - "wired-global-gateway-read", "failed to read %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message); - - ASSERT (nm_connection_verify (connection, &error), - "wired-global-gateway-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message); + NMIPAddress *ip4_addr; + char *unmanaged = NULL; - ASSERT (unmanaged == NULL, - "wired-global-gateway-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_GLOBAL_GATEWAY); + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway", + TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway", + TYPE_ETHERNET, &unmanaged, NULL, NULL, NULL, &error, NULL); + nmtst_assert_connection_verifies_without_normalization (connection); + g_assert (unmanaged == NULL); /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - ASSERT (s_con != NULL, - "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_CONNECTION_SETTING_NAME); - - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - ASSERT (tmp != NULL, - "wired-global-gateway-verify-connection", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - ASSERT (strcmp (tmp, expected_id) == 0, - "wired-global-gateway-verify-connection", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-global-gateway"); /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - ASSERT (s_wired != NULL, - "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_WIRED_SETTING_NAME); + g_assert (s_wired); /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (s_ip4 != NULL, - "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME); - - /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, - "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); /* Address #1 */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - "wired-global-gateway-verify-ip4", "failed to verify %s: missing IP4 address #1", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24, - "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); - - ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, - "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); - ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, - "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); - ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr, - "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway", - TEST_IFCFG_WIRED_GLOBAL_GATEWAY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.2"); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } -#define TEST_IFCFG_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default" -#define TEST_NETWORK_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default" - static void test_read_wired_never_default (void) { NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; GError *error = NULL; - const char *tmp; - const char *expected_id = "System test-wired-never-default"; - - connection = connection_from_file (TEST_IFCFG_WIRED_NEVER_DEFAULT, - TEST_NETWORK_WIRED_NEVER_DEFAULT, - TYPE_ETHERNET, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - ASSERT (connection != NULL, - "wired-never-default-read", "failed to read %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message); - - ASSERT (nm_connection_verify (connection, &error), - "wired-never-default-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message); - - ASSERT (unmanaged == NULL, - "wired-never-default-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_NEVER_DEFAULT); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - ASSERT (s_con != NULL, - "wired-never-default-verify-connection", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_CONNECTION_SETTING_NAME); - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - ASSERT (tmp != NULL, - "wired-never-default-verify-connection", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - ASSERT (strcmp (tmp, expected_id) == 0, - "wired-never-default-verify-connection", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default", + TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default", + TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + nmtst_assert_connection_verifies_without_normalization (connection); /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - ASSERT (s_wired != NULL, - "wired-never-default-verify-wired", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_WIRED_SETTING_NAME); + g_assert (nm_connection_get_setting_wired (connection)); /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (s_ip4 != NULL, - "wired-never-default-verify-ip4", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP4_CONFIG_SETTING_NAME); - - /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, - "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); - - ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE, - "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); - - /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 0, - "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert (nm_setting_ip_config_get_never_default (s_ip4)); + g_assert_cmpint (nm_setting_ip_config_get_num_dns (s_ip4), ==, 0); /* ===== IPv6 SETTING ===== */ - s_ip6 = nm_connection_get_setting_ip6_config (connection); - ASSERT (s_ip6 != NULL, - "wired-never-default-verify-ip6", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP6_CONFIG_SETTING_NAME); - - /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); - ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0, - "wired-never-default-verify-ip6", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); - - ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE, - "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_NEVER_DEFAULT, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + g_assert (s_ip6); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_AUTO); + g_assert (nm_setting_ip_config_get_never_default (s_ip6)); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1068,8 +889,8 @@ test_read_wired_defroute_no (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -1082,7 +903,6 @@ test_read_wired_defroute_no (void) connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -1136,18 +956,18 @@ test_read_wired_defroute_no (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE, + ASSERT (nm_setting_ip_config_get_never_default (s_ip4) == TRUE, "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); /* ===== IPv6 SETTING ===== */ @@ -1158,18 +978,18 @@ test_read_wired_defroute_no (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0, "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE, + ASSERT (nm_setting_ip_config_get_never_default (s_ip6) == TRUE, "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); g_free (unmanaged); g_free (keyfile); @@ -1187,8 +1007,8 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -1201,7 +1021,6 @@ test_read_wired_defroute_no_gatewaydev_yes (void) connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -1263,18 +1082,18 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, + ASSERT (nm_setting_ip_config_get_never_default (s_ip4) == FALSE, "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); /* ===== IPv6 SETTING ===== */ @@ -1285,18 +1104,18 @@ test_read_wired_defroute_no_gatewaydev_yes (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, - "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + tmp = nm_setting_ip_config_get_method (s_ip6); + ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0, + "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE, - "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", + ASSERT (nm_setting_ip_config_get_never_default (s_ip6) == FALSE, + "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); g_free (unmanaged); g_free (keyfile); @@ -1305,168 +1124,51 @@ test_read_wired_defroute_no_gatewaydev_yes (void) g_object_unref (connection); } -#define TEST_IFCFG_WIRED_STATIC_ROUTES TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes" - static void test_read_wired_static_routes (void) { NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; + NMSettingIPConfig *s_ip4; GError *error = NULL; - const char *tmp; - NMIP4Route *ip4_route; - guint32 addr; - const char *expected_id = "System test-wired-static-routes"; - const char *expected_dst1 = "11.22.33.0"; - const char *expected_dst2 = "44.55.66.77"; - const char *expected_gw1 = "192.168.1.5"; - const char *expected_gw2 = "192.168.1.7"; - - connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES, - NULL, - TYPE_ETHERNET, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); + NMIPRoute *ip4_route; - ASSERT (connection != NULL, - "wired-static-routes-read", - "failed to read %s: %s", - TEST_IFCFG_WIRED_STATIC_ROUTES, error->message); - - ASSERT (nm_connection_verify (connection, &error), - "wired-static-routes-verify", "failed to verify %s: %s", - TEST_IFCFG_WIRED_STATIC_ROUTES, error->message); - - ASSERT (unmanaged == NULL, - "wired-static-routes-verify", - "failed to verify %s: unexpected unmanaged value", - TEST_IFCFG_WIRED_STATIC_ROUTES); + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes", + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); + nmtst_assert_connection_verifies_without_normalization (connection); /* ===== CONNECTION SETTING ===== */ - s_con = nm_connection_get_setting_connection (connection); - ASSERT (s_con != NULL, - "wired-static-routes-verify-connection", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_CONNECTION_SETTING_NAME); - - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - ASSERT (tmp != NULL, - "wired-static-routes-verify-connection", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - ASSERT (strcmp (tmp, expected_id) == 0, - "wired-static-routes-verify-connection", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "System test-wired-static-routes"); /* ===== WIRED SETTING ===== */ - s_wired = nm_connection_get_setting_wired (connection); - ASSERT (s_wired != NULL, - "wired-static-routes-verify-wired", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_WIRED_SETTING_NAME); + g_assert (s_wired); /* ===== IPv4 SETTING ===== */ - s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (s_ip4 != NULL, - "wired-static-routes-verify-ip4", "failed to verify %s: missing %s setting", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME); - - /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + g_assert (s_ip4); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_MANUAL); /* Routes */ - ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 2, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0); - ASSERT (ip4_route, - "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #1", - TEST_IFCFG_WIRED_STATIC_ROUTES); - - ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0, - "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1", - TEST_IFCFG_WIRED_STATIC_ROUTES); - ASSERT (nm_ip4_route_get_dest (ip4_route) == addr, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix", - TEST_IFCFG_WIRED_STATIC_ROUTES); - - ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0, - "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1", - TEST_IFCFG_WIRED_STATIC_ROUTES); - ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1); - ASSERT (ip4_route, - "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #2", - TEST_IFCFG_WIRED_STATIC_ROUTES); - - ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0, - "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2", - TEST_IFCFG_WIRED_STATIC_ROUTES); - ASSERT (nm_ip4_route_get_dest (ip4_route) == addr, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix", - TEST_IFCFG_WIRED_STATIC_ROUTES); - - ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0, - "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2", - TEST_IFCFG_WIRED_STATIC_ROUTES); - ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", - TEST_IFCFG_WIRED_STATIC_ROUTES, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - ASSERT (nm_ip4_route_get_metric (ip4_route) == 3, - "wired-static-routes-verify-ip4", "failed to verify %s: unexpected route metric #2", - TEST_IFCFG_WIRED_STATIC_ROUTES); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip4), ==, 2); + + ip4_route = nm_setting_ip_config_get_route (s_ip4, 0); + g_assert (ip4_route); + g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "11.22.33.0"); + g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 24); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.5"); + g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1); + + ip4_route = nm_setting_ip_config_get_route (s_ip4, 1); + g_assert (ip4_route); + g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "44.55.66.77"); + g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "192.168.1.7"); + g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); g_object_unref (connection); } @@ -1478,7 +1180,7 @@ test_read_wired_static_routes_legacy (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -1486,20 +1188,12 @@ test_read_wired_static_routes_legacy (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - NMIP4Route *ip4_route; - guint32 addr; + NMIPRoute *ip4_route; const char *expected_id = "System test-wired-static-routes-legacy"; - const char *expected_dst1 = "21.31.41.0"; - const char *expected_dst2 = "32.42.52.62"; - const char *expected_dst3 = "43.53.0.0"; - const char *expected_gw1 = "9.9.9.9"; - const char *expected_gw2 = "8.8.8.8"; - const char *expected_gw3 = "7.7.7.7"; connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -1559,115 +1253,43 @@ test_read_wired_static_routes_legacy (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* Routes */ - ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 3, + ASSERT (nm_setting_ip_config_get_num_routes (s_ip4) == 3, "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); + NM_SETTING_IP_CONFIG_ROUTES); /* Route #1 */ - ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0); - ASSERT (ip4_route, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #1", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_dest (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_metric (ip4_route) == 1, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 metric", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ip4_route = nm_setting_ip_config_get_route (s_ip4, 0); + g_assert (ip4_route != NULL); + g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "21.31.41.0"); + g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 24); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "9.9.9.9"); + g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 1); /* Route #2 */ - ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1); - ASSERT (ip4_route, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #2", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_dest (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_metric (ip4_route) == 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 metric", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ip4_route = nm_setting_ip_config_get_route (s_ip4, 1); + g_assert (ip4_route != NULL); + g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "32.42.52.62"); + g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 32); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "8.8.8.8"); + g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, -1); /* Route #3 */ - ip4_route = nm_setting_ip4_config_get_route (s_ip4, 2); - ASSERT (ip4_route, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #3", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_dst3, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #3", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_dest (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_prefix (ip4_route) == 16, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 prefix", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - - ASSERT (inet_pton (AF_INET, expected_gw3, &addr) > 0, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #3", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); - ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES); - - ASSERT (nm_ip4_route_get_metric (ip4_route) == 3, - "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 metric", - TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY); + ip4_route = nm_setting_ip_config_get_route (s_ip4, 2); + g_assert (ip4_route != NULL); + g_assert_cmpstr (nm_ip_route_get_dest (ip4_route), ==, "43.53.0.0"); + g_assert_cmpint (nm_ip_route_get_prefix (ip4_route), ==, 16); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip4_route), ==, "7.7.7.7"); + g_assert_cmpint (nm_ip_route_get_metric (ip4_route), ==, 3); g_free (unmanaged); g_free (keyfile); @@ -1682,7 +1304,7 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -1690,19 +1312,11 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const char *expected_address1 = "1.2.3.4"; - const char *expected_address2 = "9.8.7.6"; - const char *expected_address3 = "3.3.3.3"; - guint32 expected_prefix1 = 24; - guint32 expected_prefix2 = 16; - guint32 expected_prefix3 = 8; - NMIP4Address *ip4_addr; - guint32 addr; + NMIPAddress *ip4_addr; connection = connection_from_file (file, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -1756,70 +1370,37 @@ test_read_wired_ipv4_manual (const char *file, const char *expected_id) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* IP addresses */ - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 3, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 3, "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Address #1 */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #1", - file); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix1, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", - file); - - ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #1", - file); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #1", - file); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); /* Address #2 */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 1); - ASSERT (ip4_addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #2", - file); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix2, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #2 prefix", - file); - - ASSERT (inet_pton (AF_INET, expected_address2, &addr) > 0, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #2", - file); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #2", - file); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 1); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "9.8.7.6"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 16); /* Address #3 */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 2); - ASSERT (ip4_addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: missing IP4 address #3", - file); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix3, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #3 prefix", - file); - - ASSERT (inet_pton (AF_INET, expected_address3, &addr) > 0, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: couldn't convert IP address #3", - file); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - "wired-ipv4-manual-verify-ip4", "failed to verify %s: unexpected IP4 address #3", - file); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 2); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "3.3.3.3"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); g_free (unmanaged); g_free (keyfile); @@ -1836,8 +1417,8 @@ test_read_wired_ipv6_manual (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -1846,24 +1427,14 @@ test_read_wired_ipv6_manual (void) GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-ipv6-manual"; - const char *expected_address1 = "1001:abba::1234"; - const char *expected_address2 = "2001:abba::2234"; - const char *expected_address3 = "3001:abba::3234"; - guint32 expected_prefix1 = 56; - guint32 expected_prefix2 = 64; - guint32 expected_prefix3 = 96; - const char *expected_dns1 = "1:2:3:4::a"; - const char *expected_dns2 = "1:2:3:4::b"; - NMIP6Address *ip6_addr; - NMIP6Route *ip6_route; - struct in6_addr addr; + NMIPAddress *ip6_addr; + NMIPRoute *ip6_route; g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*ignoring manual default route*"); connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_MANUAL, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -1919,54 +1490,54 @@ test_read_wired_ipv6_manual (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip4) == 2, "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS search domains */ - ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 3, + ASSERT (nm_setting_ip_config_get_num_dns_searches (s_ip4) == 3, "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0); + tmp = nm_setting_ip_config_get_dns_search (s_ip4, 0); ASSERT (tmp != NULL, "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, "lorem.com") == 0, "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1); + tmp = nm_setting_ip_config_get_dns_search (s_ip4, 1); ASSERT (tmp != NULL, "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, "ipsum.org") == 0, "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 2); + tmp = nm_setting_ip_config_get_dns_search (s_ip4, 2); ASSERT (tmp != NULL, "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, "dolor.edu") == 0, "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); /* ===== IPv6 SETTING ===== */ @@ -1977,135 +1548,92 @@ test_read_wired_ipv6_manual (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE, + ASSERT (nm_setting_ip_config_get_never_default (s_ip6) == FALSE, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); - ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE, + ASSERT (nm_setting_ip_config_get_may_fail (s_ip6) == TRUE, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_MAY_FAIL); + NM_SETTING_IP_CONFIG_MAY_FAIL); /* IP addresses */ - ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 3, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip6) == 3, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Address #1 */ - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); - ASSERT (ip6_addr, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); + g_assert (ip6_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); /* Address #2 */ - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1); - ASSERT (ip6_addr, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #2", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix2, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2 prefix", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (inet_pton (AF_INET6, expected_address2, &addr) > 0, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #2", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2", - TEST_IFCFG_WIRED_IPV6_MANUAL); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 1); + g_assert (ip6_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "2001:abba::2234"); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); /* Address #3 */ - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 2); - ASSERT (ip6_addr, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #3", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix3, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3 prefix", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (inet_pton (AF_INET6, expected_address3, &addr) > 0, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #3", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), - "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3", - TEST_IFCFG_WIRED_IPV6_MANUAL); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 2); + g_assert (ip6_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "3001:abba::3234"); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 96); /* Routes */ - g_assert_cmpint (nm_setting_ip6_config_get_num_routes (s_ip6), ==, 2); + g_assert_cmpint (nm_setting_ip_config_get_num_routes (s_ip6), ==, 2); /* Route #1 */ - ip6_route = nm_setting_ip6_config_get_route (s_ip6, 0); + ip6_route = nm_setting_ip_config_get_route (s_ip6, 0); g_assert (ip6_route); - g_assert_cmpint (inet_pton (AF_INET6, "9876::1234", &addr), >, 0); - g_assert_cmpint (memcmp (nm_ip6_route_get_dest (ip6_route), &addr, sizeof (struct in6_addr)), ==, 0); - g_assert_cmpint (nm_ip6_route_get_prefix (ip6_route), ==, 96); - g_assert_cmpint (inet_pton (AF_INET6, "9876::7777", &addr), >, 0); - g_assert_cmpint (memcmp (nm_ip6_route_get_next_hop (ip6_route), &addr, sizeof (struct in6_addr)), ==, 0); - g_assert_cmpint (nm_ip6_route_get_metric (ip6_route), ==, 2); + g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "9876::1234"); + g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 96); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, "9876::7777"); + g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, 2); /* Route #2 */ - ip6_route = nm_setting_ip6_config_get_route (s_ip6, 1); + ip6_route = nm_setting_ip_config_get_route (s_ip6, 1); g_assert (ip6_route); - g_assert_cmpint (inet_pton (AF_INET6, "abbe::cafe", &addr), >, 0); - g_assert_cmpint (memcmp (nm_ip6_route_get_dest (ip6_route), &addr, sizeof (struct in6_addr)), ==, 0); - g_assert_cmpint (nm_ip6_route_get_prefix (ip6_route), ==, 64); - g_assert_cmpint (inet_pton (AF_INET6, "::", &addr), >, 0); - g_assert_cmpint (memcmp (nm_ip6_route_get_next_hop (ip6_route), &addr, sizeof (struct in6_addr)), ==, 0); - g_assert_cmpint (nm_ip6_route_get_metric (ip6_route), ==, 777); + g_assert_cmpstr (nm_ip_route_get_dest (ip6_route), ==, "abbe::cafe"); + g_assert_cmpint (nm_ip_route_get_prefix (ip6_route), ==, 64); + g_assert_cmpstr (nm_ip_route_get_next_hop (ip6_route), ==, NULL); + g_assert_cmpint (nm_ip_route_get_metric (ip6_route), ==, 777); /* DNS Addresses */ - ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip6) == 2, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr), + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip6, 0), "1:2:3:4::a") == 0, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0, - "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr), + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip6, 1), "1:2:3:4::b") == 0, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #2", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS domains - none as domains are stuffed to 'ipv4' setting */ - ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0, + ASSERT (nm_setting_ip_config_get_num_dns_searches (s_ip6) == 0, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); g_free (unmanaged); g_free (keyfile); @@ -2122,8 +1650,8 @@ test_read_wired_ipv6_only (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -2132,17 +1660,12 @@ test_read_wired_ipv6_only (void) GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-ipv6-only"; - const char *expected_address1 = "1001:abba::1234"; - guint32 expected_prefix1 = 56; - const char *expected_dns1 = "1:2:3:4::a"; - NMIP6Address *ip6_addr; - struct in6_addr addr; + NMIPAddress *ip6_addr; const char *method; connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2195,12 +1718,12 @@ test_read_wired_ipv6_only (void) TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME); - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, "wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== IPv6 SETTING ===== */ @@ -2211,58 +1734,44 @@ test_read_wired_ipv6_only (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* IP addresses */ - ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip6) == 1, "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Address #1 */ - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); - ASSERT (ip6_addr, - "wired-ipv6-only-verify-ip6", "failed to verify %s: missing IP6 address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1, - "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix", - TEST_IFCFG_WIRED_IPV6_MANUAL); - - ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0, - "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert IP address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr), - "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); + g_assert (ip6_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "1001:abba::1234"); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 56); /* DNS Addresses */ - ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 1, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip6) == 1, "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, - "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_IFCFG_WIRED_IPV6_MANUAL); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr), + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip6, 0), "1:2:3:4::a") == 0, "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1", TEST_IFCFG_WIRED_IPV6_MANUAL, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS domains should be in IPv6, because IPv4 is disabled */ - g_assert_cmpint (nm_setting_ip6_config_get_num_dns_searches (s_ip6), ==, 3); - g_assert_cmpstr (nm_setting_ip6_config_get_dns_search (s_ip6, 0), ==, "lorem.com"); - g_assert_cmpstr (nm_setting_ip6_config_get_dns_search (s_ip6, 1), ==, "ipsum.org"); - g_assert_cmpstr (nm_setting_ip6_config_get_dns_search (s_ip6, 2), ==, "dolor.edu"); + g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 3); + g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "lorem.com"); + g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "ipsum.org"); + g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 2), ==, "dolor.edu"); g_free (unmanaged); g_free (keyfile); @@ -2279,8 +1788,8 @@ test_read_wired_dhcp6_only (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -2294,7 +1803,6 @@ test_read_wired_dhcp6_only (void) connection = connection_from_file (TEST_IFCFG_WIRED_DHCP6_ONLY, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2347,12 +1855,12 @@ test_read_wired_dhcp6_only (void) TEST_IFCFG_WIRED_DHCP6_ONLY, NM_SETTING_IP4_CONFIG_SETTING_NAME); - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, "wired-dhcp6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP6_ONLY, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== IPv6 SETTING ===== */ @@ -2363,12 +1871,12 @@ test_read_wired_dhcp6_only (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0, "wired-dhcp6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_DHCP6_ONLY, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -2394,7 +1902,6 @@ test_read_onboot_no (void) connection = connection_from_file (TEST_IFCFG_ONBOOT_NO, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2438,8 +1945,8 @@ static void test_read_noip (void) { NMConnection *connection; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -2450,7 +1957,6 @@ test_read_noip (void) connection = connection_from_file (TEST_IFCFG_NOIP, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2463,13 +1969,13 @@ test_read_noip (void) s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); - g_assert (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_DISABLED); + g_assert (nm_setting_ip_config_get_never_default (s_ip4) == FALSE); s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip6); - g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); - g_assert (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip6), ==, NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + g_assert (nm_setting_ip_config_get_never_default (s_ip6) == FALSE); g_free (unmanaged); g_free (keyfile); @@ -2486,7 +1992,7 @@ test_read_wired_8021x_peap_mschapv2 (void) { NMConnection *connection; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; NMSetting8021x *tmp_8021x; char *unmanaged = NULL; @@ -2506,7 +2012,6 @@ test_read_wired_8021x_peap_mschapv2 (void) connection = connection_from_file (TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2539,12 +2044,12 @@ test_read_wired_8021x_peap_mschapv2 (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ s_8021x = nm_connection_get_setting_802_1x (connection); @@ -2700,7 +2205,6 @@ test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags connection = connection_from_file (ifcfg, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2757,7 +2261,7 @@ test_read_write_802_1X_subj_matches (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing IEEE_8021X_CA_CERT*peap*"); connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1X-subj-matches", - NULL, TYPE_ETHERNET, NULL, NULL, + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); g_assert_no_error (error); @@ -2786,12 +2290,12 @@ test_read_write_802_1X_subj_matches (void) g_assert (success); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*missing IEEE_8021X_CA_CERT*peap*"); - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, + reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); unlink (written); @@ -2840,7 +2344,7 @@ test_read_802_1x_ttls_eapgtc (void) */ connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-802-1x-ttls-eapgtc", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -2869,7 +2373,7 @@ test_read_wired_aliases_good (void) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -2878,16 +2382,15 @@ test_read_wired_aliases_good (void) GError *error = NULL; const char *tmp; const char *expected_id = "System aliasem0"; - int expected_num_addresses = 4, expected_prefix = 24; + int expected_num_addresses = 4; const char *expected_address[4] = { "192.168.1.5", "192.168.1.6", "192.168.1.9", "192.168.1.99" }; const char *expected_label[4] = { NULL, "aliasem0:1", "aliasem0:2", "aliasem0:99" }; - const char *expected_gateway[4] = { "192.168.1.1", "192.168.1.1", "192.168.1.1", "192.168.1.1" }; + const char *expected_gateway = "192.168.1.1"; int i, j; connection = connection_from_file (TEST_IFCFG_ALIASES_GOOD, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -2930,74 +2433,51 @@ test_read_wired_aliases_good (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "aliases-good-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_ALIASES_GOOD, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == expected_num_addresses, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == expected_num_addresses, "aliases-good-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_ALIASES_GOOD, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Addresses */ for (i = 0; i < expected_num_addresses; i++) { - NMIP4Address *ip4_addr; - char buf[INET_ADDRSTRLEN]; - struct in_addr addr; + NMIPAddress *ip4_addr; + const char *addr; + GVariant *label; - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, i); - ASSERT (ip4_addr, - "aliases-good-verify-ip4", "failed to verify %s: missing IP4 address #%d", - TEST_IFCFG_ALIASES_GOOD, - i); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, i); + g_assert (ip4_addr != NULL); - addr.s_addr = nm_ip4_address_get_address (ip4_addr); - ASSERT (inet_ntop (AF_INET, &addr, buf, sizeof (buf)) > 0, - "aliases-good-verify-ip4", "failed to verify %s: couldn't convert IP address #%d", - TEST_IFCFG_ALIASES_GOOD, - i); + addr = nm_ip_address_get_address (ip4_addr); + g_assert (nm_utils_ipaddr_valid (AF_INET, addr)); for (j = 0; j < expected_num_addresses; j++) { - if (!g_strcmp0 (buf, expected_address[j])) + if (!g_strcmp0 (addr, expected_address[j])) break; } + g_assert (j < expected_num_addresses); - ASSERT (j < expected_num_addresses, - "aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address #%d", - TEST_IFCFG_ALIASES_GOOD, - i); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, - "aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address prefix #%d", - TEST_IFCFG_ALIASES_GOOD, - i); - - if (expected_gateway[j]) { - ASSERT (inet_pton (AF_INET, expected_gateway[j], &addr) > 0, - "aliases-good-verify-ip4", "failed to verify %s: couldn't convert IP address gateway #%d", - TEST_IFCFG_ALIASES_GOOD, - i); - } else - addr.s_addr = 0; - ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, - "aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address gateway #%d", - TEST_IFCFG_ALIASES_GOOD, - i); - - ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), expected_label[j]) == 0, - "aliases-good-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d", - TEST_IFCFG_ALIASES_GOOD, - i); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + label = nm_ip_address_get_attribute (ip4_addr, "label"); + if (expected_label[j]) + g_assert_cmpstr (g_variant_get_string (label, NULL), ==, expected_label[j]); + else + g_assert (label == NULL); expected_address[j] = NULL; - expected_gateway[j] = NULL; expected_label[j] = NULL; } + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, expected_gateway); + for (i = 0; i < expected_num_addresses; i++) { ASSERT (expected_address[i] == NULL, "aliases-good-verify-ip4", "failed to verify %s: did not find IP4 address %s", @@ -3016,7 +2496,7 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -3024,17 +2504,11 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - int expected_num_addresses = 1, expected_prefix = 24; - const char *expected_address = "192.168.1.5"; - const char *expected_label = NULL; - const char *expected_gateway = "192.168.1.1"; - NMIP4Address *ip4_addr; - struct in_addr addr; + NMIPAddress *ip4_addr; connection = connection_from_file (base, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -3078,46 +2552,28 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "aliases-bad-verify-ip4", "failed to verify %s: unexpected %s / %s key value", base, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == expected_num_addresses, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 1, "aliases-bad-verify-ip4", "failed to verify %s: unexpected %s / %s key value", base, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Addresses */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - "aliases-bad-verify-ip4", "failed to verify %s: missing IP4 address", - base); - - ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0, - "aliases-bad-verify-ip4", "failed to verify %s: couldn't convert IP address", - base); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr, - "aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address", - base); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, - "aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address prefix", - base); - - ASSERT (inet_pton (AF_INET, expected_gateway, &addr) > 0, - "aliases-bad-verify-ip4", "failed to verify %s: couldn't convert IP address gateway", - base); - ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr, - "aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address gateway", - base); - - ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, 0)), expected_label) == 0, - "aliases-bad-verify-ip4", "failed to verify %s: unexpected IP4 address label", - base); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24); + g_assert (nm_ip_address_get_attribute (ip4_addr, "label") == NULL); + + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1"); g_free (keyfile); g_free (routefile); @@ -3154,7 +2610,7 @@ test_read_wifi_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -3162,7 +2618,8 @@ test_read_wifi_open (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_id = "System blahblah (test-wifi-open)"; guint64 expected_timestamp = 0; @@ -3173,7 +2630,6 @@ test_read_wifi_open (void) connection = connection_from_file (TEST_IFCFG_WIFI_OPEN, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3226,6 +2682,8 @@ test_read_wifi_open (void) NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT); + g_assert_cmpint (nm_setting_connection_get_autoconnect_priority (s_con), ==, -1); + /* ===== WIRELESS SETTING ===== */ s_wireless = nm_connection_get_setting_wireless (connection); @@ -3235,18 +2693,13 @@ test_read_wifi_open (void) NM_SETTING_WIRELESS_SETTING_NAME); /* MAC address */ - array = nm_setting_wireless_get_mac_address (s_wireless); - ASSERT (array != NULL, + mac = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (mac != NULL, "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_OPEN, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_WIFI_OPEN, - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_OPEN, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3258,18 +2711,18 @@ test_read_wifi_open (void) NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MTU); - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_OPEN, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_OPEN, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_OPEN, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3312,12 +2765,12 @@ test_read_wifi_open (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-open-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_OPEN, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -3347,7 +2800,6 @@ test_read_wifi_open_auto (void) connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_AUTO, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3423,14 +2875,13 @@ test_read_wifi_open_ssid_hex (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; const char *expected_id = "System blahblah (test-wifi-open-ssid-hex)"; const char *expected_ssid = "blahblah"; connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_HEX, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3473,18 +2924,18 @@ test_read_wifi_open_ssid_hex (void) NM_SETTING_WIRELESS_SETTING_NAME); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_OPEN_SSID_HEX, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_OPEN_SSID_HEX, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_OPEN_SSID_HEX, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3511,7 +2962,6 @@ test_read_wifi_open_ssid_bad (const char *file, const char *test) connection = connection_from_file (file, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3542,14 +2992,13 @@ test_read_wifi_open_ssid_quoted (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; const char *expected_id = "System foo\"bar\\ (test-wifi-open-ssid-quoted)"; const char *expected_ssid = "foo\"bar\\"; connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3592,18 +3041,18 @@ test_read_wifi_open_ssid_quoted (void) NM_SETTING_WIRELESS_SETTING_NAME); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3625,7 +3074,7 @@ test_read_wifi_wep (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -3633,7 +3082,8 @@ test_read_wifi_wep (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_id = "System blahblah (test-wifi-wep)"; guint64 expected_timestamp = 0; @@ -3646,7 +3096,6 @@ test_read_wifi_wep (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3708,18 +3157,13 @@ test_read_wifi_wep (void) NM_SETTING_WIRELESS_SETTING_NAME); /* MAC address */ - array = nm_setting_wireless_get_mac_address (s_wireless); - ASSERT (array != NULL, + mac = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (mac != NULL, "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WEP, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_WIFI_WEP, - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3733,18 +3177,18 @@ test_read_wifi_wep (void) NM_SETTING_WIRELESS_MTU); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WEP, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_WEP, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP, NM_SETTING_WIRELESS_SETTING_NAME, @@ -3865,12 +3309,12 @@ test_read_wifi_wep (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wep-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -3888,7 +3332,7 @@ test_read_wifi_wep_adhoc (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -3896,19 +3340,15 @@ test_read_wifi_wep_adhoc (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; const char *expected_id = "System blahblah (test-wifi-wep-adhoc)"; const char *expected_ssid = "blahblah"; const char *expected_mode = "adhoc"; const char *expected_wep_key0 = "0123456789abcdef0123456789"; - guint32 addr; - const char *expected_dns1 = "4.2.2.1"; - const char *expected_dns2 = "4.2.2.2"; connection = connection_from_file (TEST_IFCFG_WIFI_WEP_ADHOC, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -3963,18 +3403,18 @@ test_read_wifi_wep_adhoc (void) NM_SETTING_WIRELESS_SETTING_NAME); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_WIRELESS_SETTING_NAME, @@ -4083,48 +3523,38 @@ test_read_wifi_wep_adhoc (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* Ignore auto DNS */ - ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE, + ASSERT (nm_setting_ip_config_get_ignore_auto_dns (s_ip4) == TRUE, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS); + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS); /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip4) == 2, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, - "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_IFCFG_WIFI_WEP_ADHOC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 0), "4.2.2.1") == 0, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, - "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_IFCFG_WIFI_WEP_ADHOC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 1), "4.2.2.2") == 0, "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", TEST_IFCFG_WIFI_WEP_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); g_free (unmanaged); g_free (keyfile); @@ -4155,7 +3585,6 @@ test_read_wifi_wep_passphrase (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_PASSPHRASE, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4281,7 +3710,6 @@ test_read_wifi_wep_40_ascii (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_40_ASCII, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4405,7 +3833,6 @@ test_read_wifi_wep_104_ascii (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_104_ASCII, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4530,7 +3957,6 @@ test_read_wifi_leap (void) connection = connection_from_file (TEST_IFCFG_WIFI_LEAP, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4654,7 +4080,6 @@ test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expecte connection = connection_from_file (file, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4699,7 +4124,7 @@ test_read_wifi_wpa_psk (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -4707,7 +4132,8 @@ test_read_wifi_wpa_psk (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; const char *expected_id = "System blahblah (test-wifi-wpa-psk)"; guint64 expected_timestamp = 0; @@ -4729,7 +4155,6 @@ test_read_wifi_wpa_psk (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -4791,18 +4216,13 @@ test_read_wifi_wpa_psk (void) NM_SETTING_WIRELESS_SETTING_NAME); /* MAC address */ - array = nm_setting_wireless_get_mac_address (s_wireless); - ASSERT (array != NULL, + mac = nm_setting_wireless_get_mac_address (s_wireless); + ASSERT (mac != NULL, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_WIFI_WPA_PSK, - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_WIRELESS_SETTING_NAME, @@ -4816,18 +4236,18 @@ test_read_wifi_wpa_psk (void) NM_SETTING_WIRELESS_MTU); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_WIRELESS_SETTING_NAME, @@ -4982,12 +4402,12 @@ test_read_wifi_wpa_psk (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wpa-psk-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -5018,7 +4438,6 @@ test_read_wifi_wpa_psk_2 (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_2, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5110,7 +4529,6 @@ test_read_wifi_wpa_psk_unquoted (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5200,7 +4618,6 @@ test_read_wifi_wpa_psk_unquoted2 (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5226,7 +4643,7 @@ test_read_wifi_wpa_psk_adhoc (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -5244,7 +4661,6 @@ test_read_wifi_wpa_psk_adhoc (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_ADHOC, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5382,12 +4798,12 @@ test_read_wifi_wpa_psk_adhoc (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -5405,7 +4821,7 @@ test_read_wifi_wpa_psk_hex (void) NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -5413,7 +4829,7 @@ test_read_wifi_wpa_psk_hex (void) gboolean ignore_error = FALSE; GError *error = NULL; const char *tmp; - const GByteArray *array; + GBytes *ssid; const char *expected_id = "System blahblah (test-wifi-wpa-psk-hex)"; const char *expected_ssid = "blahblah"; const char *expected_key_mgmt = "wpa-psk"; @@ -5422,7 +4838,6 @@ test_read_wifi_wpa_psk_hex (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_HEX, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5465,18 +4880,18 @@ test_read_wifi_wpa_psk_hex (void) NM_SETTING_WIRELESS_SETTING_NAME); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_IFCFG_WIFI_WPA_PSK_HEX, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (array->len == strlen (expected_ssid), + ASSERT (g_bytes_get_size (ssid) == strlen (expected_ssid), "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", TEST_IFCFG_WIFI_WPA_PSK_HEX, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0, + ASSERT (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0, "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK_HEX, NM_SETTING_WIRELESS_SETTING_NAME, @@ -5525,12 +4940,12 @@ test_read_wifi_wpa_psk_hex (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_PSK_HEX, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -5549,7 +4964,7 @@ test_read_wifi_wpa_eap_tls (void) { NMConnection *connection; NMSettingWireless *s_wireless; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; char *keyfile = NULL; @@ -5564,7 +4979,6 @@ test_read_wifi_wpa_eap_tls (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TLS, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -5597,12 +5011,12 @@ test_read_wifi_wpa_eap_tls (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_EAP_TLS, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ s_8021x = nm_connection_get_setting_802_1x (connection); @@ -5690,7 +5104,7 @@ test_read_wifi_wpa_eap_ttls_tls (void) { NMConnection *connection; NMSettingWireless *s_wireless; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; char *keyfile = NULL; @@ -5705,7 +5119,6 @@ test_read_wifi_wpa_eap_ttls_tls (void) connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5738,12 +5151,12 @@ test_read_wifi_wpa_eap_ttls_tls (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ s_8021x = nm_connection_get_setting_802_1x (connection); @@ -5860,7 +5273,6 @@ test_read_wifi_dynamic_wep_leap (void) connection = connection_from_file (TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5923,7 +5335,7 @@ test_read_wifi_wep_eap_ttls_chap (void) NMConnection *connection; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSetting8021x *s_8021x; char *unmanaged = NULL; char *keyfile = NULL; @@ -5939,7 +5351,6 @@ test_read_wifi_wep_eap_ttls_chap (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -5972,12 +5383,12 @@ test_read_wifi_wep_eap_ttls_chap (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* ===== 802.1x SETTING ===== */ s_wsec = nm_connection_get_setting_wireless_security (connection); @@ -6086,7 +5497,7 @@ test_read_wifi_hidden (void) GError *error = NULL; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-hidden", - NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -6115,10 +5526,10 @@ test_write_wifi_hidden (void) gboolean success; GError *error = NULL; shvarFile *f; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -6136,8 +5547,7 @@ test_write_wifi_hidden (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, @@ -6145,7 +5555,7 @@ test_write_wifi_hidden (void) NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); success = nm_connection_verify (connection, &error); g_assert_no_error (error); @@ -6171,10 +5581,124 @@ test_write_wifi_hidden (void) svCloseFile (f); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, + NULL, NULL, NULL, NULL, &error, NULL); + unlink (testfile); + g_assert_no_error (error); + g_assert (reread); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + g_free (testfile); + g_object_unref (connection); + g_object_unref (reread); +} + +static void +test_read_wifi_band_a (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + gboolean success; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a", + NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRELESS_SETTING_NAME); + + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); + g_assert_cmpstr (nm_setting_wireless_get_band (s_wifi), ==, "a"); + + g_object_unref (connection); +} + +static void +test_write_wifi_band_a (void) +{ + NMConnection *connection, *reread; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + char *uuid, *testfile = NULL, *val; + gboolean success; + GError *error = NULL; + shvarFile *f; + GBytes *ssid; + const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write WiFi Band A", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); + + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NM_SETTING_WIRELESS_BAND, "a", + NULL); + + g_bytes_unref (ssid); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + + f = svOpenFile (testfile, &error); + g_assert_no_error (error); + g_assert (f); + + /* re-read the file to check that what key was written. */ + val = svGetValue (f, "BAND", FALSE); + g_assert (val); + g_assert_cmpstr (val, ==, "a"); + g_free (val); + svCloseFile (f); + + /* reread will be normalized, so we must normalize connection too. */ + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL, + reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); unlink (testfile); g_assert_no_error (error); @@ -6191,6 +5715,30 @@ test_write_wifi_hidden (void) g_object_unref (reread); } +static void +test_read_wifi_band_a_channel_mismatch (void) +{ + NMConnection *connection; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-a-channel-mismatch", + NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + g_assert (connection == NULL); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); +} + +static void +test_read_wifi_band_bg_channel_mismatch (void) +{ + NMConnection *connection; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-band-bg-channel-mismatch", + NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); + g_assert (connection == NULL); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); +} + #define TEST_IFCFG_WIRED_QETH_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-qeth-static" static void @@ -6199,7 +5747,7 @@ test_read_wired_qeth_static (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *keyfile = NULL; char *routefile = NULL; @@ -6208,16 +5756,15 @@ test_read_wired_qeth_static (void) GError *error = NULL; const char *tmp; const char *expected_id = "System test-wired-qeth-static"; - const GByteArray *array; + const char *mac; const char *expected_channel0 = "0.0.0600"; const char *expected_channel1 = "0.0.0601"; const char *expected_channel2 = "0.0.0602"; - const GPtrArray *subchannels; + const char * const *subchannels; connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -6263,8 +5810,8 @@ test_read_wired_qeth_static (void) NM_SETTING_WIRED_SETTING_NAME); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array == NULL, + mac = nm_setting_wired_get_mac_address (s_wired); + ASSERT (mac == NULL, "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key", TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_WIRED_SETTING_NAME, @@ -6277,24 +5824,19 @@ test_read_wired_qeth_static (void) TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_SUBCHANNELS); - ASSERT (subchannels->len == 3, + ASSERT (subchannels[0] && subchannels[1] && subchannels[2] && !subchannels[3], "wired-qeth-static-verify-wired", "failed to verify %s: invalid %s / %s key (not 3 elements)", TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_SUBCHANNELS); - tmp = (const char *) g_ptr_array_index (subchannels, 0); - ASSERT (strcmp (tmp, expected_channel0) == 0, + ASSERT (strcmp (subchannels[0], expected_channel0) == 0, "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #0", TEST_IFCFG_WIRED_QETH_STATIC); - - tmp = (const char *) g_ptr_array_index (subchannels, 1); - ASSERT (strcmp (tmp, expected_channel1) == 0, + ASSERT (strcmp (subchannels[1], expected_channel1) == 0, "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #1", TEST_IFCFG_WIRED_QETH_STATIC); - - tmp = (const char *) g_ptr_array_index (subchannels, 2); - ASSERT (strcmp (tmp, expected_channel2) == 0, + ASSERT (strcmp (subchannels[2], expected_channel2) == 0, "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #2", TEST_IFCFG_WIRED_QETH_STATIC); @@ -6353,12 +5895,12 @@ test_read_wired_qeth_static (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "wired-qeth-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_WIRED_QETH_STATIC, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_free (unmanaged); g_free (keyfile); @@ -6385,13 +5927,12 @@ test_read_wired_ctc_static (void) const char *expected_id = "System test-wired-ctc-static"; const char *expected_channel0 = "0.0.1b00"; const char *expected_channel1 = "0.0.1b01"; - const GPtrArray *subchannels; + const char * const *subchannels; gboolean success; connection = connection_from_file (TEST_IFCFG_WIRED_CTC_STATIC, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -6420,10 +5961,10 @@ test_read_wired_ctc_static (void) /* Subchannels */ subchannels = nm_setting_wired_get_s390_subchannels (s_wired); g_assert (subchannels != NULL); - g_assert_cmpint (subchannels->len, ==, 2); + g_assert (subchannels[0] && subchannels[1] && !subchannels[2]); - g_assert_cmpstr (g_ptr_array_index (subchannels, 0), ==, expected_channel0); - g_assert_cmpstr (g_ptr_array_index (subchannels, 1), ==, expected_channel1); + g_assert_cmpstr (subchannels[0], ==, expected_channel0); + g_assert_cmpstr (subchannels[1], ==, expected_channel1); /* Nettype */ g_assert_cmpstr (nm_setting_wired_get_s390_nettype (s_wired), ==, "ctc"); @@ -6462,7 +6003,6 @@ test_read_wifi_wep_no_keys (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_NO_KEYS, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -6572,7 +6112,6 @@ test_read_permissions (void) connection = connection_from_file (TEST_IFCFG_PERMISSIONS, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -6648,7 +6187,6 @@ test_read_wifi_wep_agent_keys (void) connection = connection_from_file (TEST_IFCFG_WIFI_WEP_AGENT_KEYS, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -6699,30 +6237,22 @@ test_write_wired_static (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4, *reread_s_ip4; - NMSettingIP6Config *s_ip6, *reread_s_ip6; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + NMSettingIPConfig *s_ip4, *reread_s_ip4; + NMSettingIPConfig *s_ip6, *reread_s_ip6; + static const char *mac = "31:33:33:37:be:cd"; guint32 mtu = 1492; char *uuid; - const guint32 ip1 = htonl (0x01010103); - const guint32 ip2 = htonl (0x01010105); - const guint32 gw = htonl (0x01010101); - const guint32 dns1 = htonl (0x04020201); - const guint32 dns2 = htonl (0x04020202); - const guint32 prefix = 24; + const char *dns1 = "4.2.2.1"; + const char *dns2 = "4.2.2.2"; const char *dns_search1 = "foobar.com"; const char *dns_search2 = "lab.foobar.com"; const char *dns_search3 = "foobar6.com"; const char *dns_search4 = "lab6.foobar.com"; - struct in6_addr ip6, ip6_1, ip6_2; - struct in6_addr route1_dest, route2_dest, route1_nexthop, route2_nexthop; - struct in6_addr dns6_1, dns6_2; - const guint32 route1_prefix = 64, route2_prefix = 128; - const guint32 route1_metric = 99, route2_metric = 1; - NMIP4Address *addr; - NMIP6Address *addr6; - NMIP6Route *route6; + const char *dns6_1 = "fade:0102:0103::face"; + const char *dns6_2 = "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed"; + NMIPAddress *addr; + NMIPAddress *addr6; + NMIPRoute *route6; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -6732,17 +6262,7 @@ test_write_wired_static (void) char *route6file = NULL; gboolean ignore_error = FALSE; - inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6); - inet_pton (AF_INET6, "2003:1234:abcd::2", &ip6_1); - inet_pton (AF_INET6, "3003:1234:abcd::3", &ip6_2); - inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc::", &route1_dest); - inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", &route1_nexthop); - inet_pton (AF_INET6, "::", &route2_dest); - inet_pton (AF_INET6, "2222:aaaa::9999", &route2_nexthop); - inet_pton (AF_INET6, "fade:0102:0103::face", &dns6_1); - inet_pton (AF_INET6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed", &dns6_2); - - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -6761,96 +6281,82 @@ test_write_wired_static (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", NULL); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip2); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - nm_setting_ip4_config_add_dns (s_ip4, dns1); - nm_setting_ip4_config_add_dns (s_ip4, dns2); + nm_setting_ip_config_add_dns (s_ip4, dns1); + nm_setting_ip_config_add_dns (s_ip4, dns2); - nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1); - nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2); + nm_setting_ip_config_add_dns_search (s_ip4, dns_search1); + nm_setting_ip_config_add_dns_search (s_ip4, dns_search2); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Add addresses */ - addr6 = nm_ip6_address_new (); - nm_ip6_address_set_address (addr6, &ip6); - nm_ip6_address_set_prefix (addr6, 11); - nm_setting_ip6_config_add_address (s_ip6, addr6); - nm_ip6_address_unref (addr6); - - addr6 = nm_ip6_address_new (); - nm_ip6_address_set_address (addr6, &ip6_1); - nm_ip6_address_set_prefix (addr6, 22); - nm_setting_ip6_config_add_address (s_ip6, addr6); - nm_ip6_address_unref (addr6); - - addr6 = nm_ip6_address_new (); - nm_ip6_address_set_address (addr6, &ip6_2); - nm_ip6_address_set_prefix (addr6, 33); - nm_setting_ip6_config_add_address (s_ip6, addr6); - nm_ip6_address_unref (addr6); + addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr6); + nm_ip_address_unref (addr6); + + addr6 = nm_ip_address_new (AF_INET6, "2003:1234:abcd::2", 22, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr6); + nm_ip_address_unref (addr6); + + addr6 = nm_ip_address_new (AF_INET6, "3003:1234:abcd::3", 33, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr6); + nm_ip_address_unref (addr6); /* Add routes */ - route6 = nm_ip6_route_new (); - nm_ip6_route_set_dest (route6, &route1_dest); - nm_ip6_route_set_prefix (route6, route1_prefix); - nm_ip6_route_set_next_hop (route6, &route1_nexthop); - nm_ip6_route_set_metric (route6, route1_metric); - nm_setting_ip6_config_add_route (s_ip6, route6); - nm_ip6_route_unref (route6); - - route6 = nm_ip6_route_new (); - nm_ip6_route_set_dest (route6, &route2_dest); - nm_ip6_route_set_prefix (route6, route2_prefix); - nm_ip6_route_set_next_hop (route6, &route2_nexthop); - nm_ip6_route_set_metric (route6, route2_metric); - nm_setting_ip6_config_add_route (s_ip6, route6); - nm_ip6_route_unref (route6); + route6 = nm_ip_route_new (AF_INET6, + "2222:aaaa:bbbb:cccc::", 64, + "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", 99, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_route (s_ip6, route6); + nm_ip_route_unref (route6); + + route6 = nm_ip_route_new (AF_INET6, "::", 128, "2222:aaaa::9999", 1, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_route (s_ip6, route6); + nm_ip_route_unref (route6); /* DNS servers */ - nm_setting_ip6_config_add_dns (s_ip6, &dns6_1); - nm_setting_ip6_config_add_dns (s_ip6, &dns6_2); + nm_setting_ip_config_add_dns (s_ip6, dns6_1); + nm_setting_ip_config_add_dns (s_ip6, dns6_2); /* DNS domains */ - nm_setting_ip6_config_add_dns_search (s_ip6, dns_search3); - nm_setting_ip6_config_add_dns_search (s_ip6, dns_search4); + nm_setting_ip_config_add_dns_search (s_ip6, dns_search3); + nm_setting_ip_config_add_dns_search (s_ip6, dns_search4); ASSERT (nm_connection_verify (connection, &error) == TRUE, "wired-static-write", "failed to verify connection: %s", @@ -6869,13 +6375,12 @@ test_write_wired_static (void) "wired-static-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -6896,10 +6401,10 @@ test_write_wired_static (void) */ reread_s_ip4 = nm_connection_get_setting_ip4_config (reread); reread_s_ip6 = nm_connection_get_setting_ip6_config (reread); - nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 2)); - nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 3)); - nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 3); - nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 2); + nm_setting_ip_config_add_dns_search (reread_s_ip6, nm_setting_ip_config_get_dns_search (reread_s_ip4, 2)); + nm_setting_ip_config_add_dns_search (reread_s_ip6, nm_setting_ip_config_get_dns_search (reread_s_ip4, 3)); + nm_setting_ip_config_remove_dns_search (reread_s_ip4, 3); + nm_setting_ip_config_remove_dns_search (reread_s_ip4, 2); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, "wired-static-write", "written and re-read connection weren't the same."); @@ -6923,8 +6428,8 @@ test_write_wired_dhcp (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -6935,7 +6440,7 @@ test_write_wired_dhcp (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -6955,15 +6460,15 @@ test_write_wired_dhcp (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33", - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, "awesome-hostname", - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, TRUE, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, TRUE, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "awesome-hostname", + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -6971,12 +6476,12 @@ test_write_wired_dhcp (void) (error && error->message) ? error->message : "(unknown)"); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Save the ifcfg */ @@ -6992,13 +6497,12 @@ test_write_wired_dhcp (void) "wired-dhcp-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -7034,7 +6538,7 @@ test_write_wired_dhcp_plus_ip (void) gboolean success = FALSE; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-plus-ip", - NULL, TYPE_ETHERNET, NULL, NULL, + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection != NULL); @@ -7046,10 +6550,10 @@ test_write_wired_dhcp_plus_ip (void) g_assert (success); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, + reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); unlink (written); g_free (written); @@ -7072,15 +6576,15 @@ static void test_read_write_wired_dhcp_send_hostname (void) { NMConnection *connection, *reread; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; const char * dhcp_hostname = "kamil-patka"; char *written = NULL; GError *error = NULL; gboolean success = FALSE; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp-send-hostname", - NULL, TYPE_ETHERNET, NULL, NULL, + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection != NULL); @@ -7090,14 +6594,14 @@ test_read_write_wired_dhcp_send_hostname (void) s_ip6 = nm_connection_get_setting_ip6_config (connection); g_assert (s_ip4); g_assert (s_ip6); - g_assert (nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) == TRUE); - g_assert_cmpstr (nm_setting_ip4_config_get_dhcp_hostname (s_ip4), ==, "svata-pulec"); - g_assert_cmpstr (nm_setting_ip6_config_get_dhcp_hostname (s_ip6), ==, "svata-pulec"); + g_assert (nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) == TRUE); + g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, "svata-pulec"); + g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, "svata-pulec"); /* Set dhcp-send-hostname=false dhcp-hostname="kamil-patka" and write the connection. */ - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, FALSE, NULL); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); - g_object_set (s_ip6, NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, FALSE, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); success = writer_new_connection (connection, TEST_SCRATCH_DIR "/network-scripts/", @@ -7106,10 +6610,10 @@ test_read_write_wired_dhcp_send_hostname (void) g_assert (success); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, + reread = connection_from_file (written, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); unlink (written); g_free (written); @@ -7129,9 +6633,9 @@ test_read_write_wired_dhcp_send_hostname (void) s_ip6 = nm_connection_get_setting_ip6_config (reread); g_assert (s_ip4); g_assert (s_ip6); - g_assert (nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) == FALSE); - g_assert_cmpstr (nm_setting_ip4_config_get_dhcp_hostname (s_ip4), ==, dhcp_hostname); - g_assert_cmpstr (nm_setting_ip6_config_get_dhcp_hostname (s_ip6), ==, dhcp_hostname); + g_assert (nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) == FALSE); + g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip4), ==, dhcp_hostname); + g_assert_cmpstr (nm_setting_ip_config_get_dhcp_hostname (s_ip6), ==, dhcp_hostname); g_object_unref (connection); g_object_unref (reread); @@ -7144,14 +6648,12 @@ test_write_wired_static_ip6_only (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + static const char *mac = "31:33:33:37:be:cd"; char *uuid; - struct in6_addr ip6; - struct in6_addr dns6; - NMIP6Address *addr6; + const char *dns6 = "fade:0102:0103::face"; + NMIPAddress *addr6; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -7161,10 +6663,7 @@ test_write_wired_static_ip6_only (void) char *route6file = NULL; gboolean ignore_error = FALSE; - inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6); - inet_pton (AF_INET6, "fade:0102:0103::face", &dns6); - - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -7183,36 +6682,32 @@ test_write_wired_static_ip6_only (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); /* Add addresses */ - addr6 = nm_ip6_address_new (); - nm_ip6_address_set_address (addr6, &ip6); - nm_ip6_address_set_prefix (addr6, 11); - nm_setting_ip6_config_add_address (s_ip6, addr6); - nm_ip6_address_unref (addr6); + addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr6); + nm_ip_address_unref (addr6); /* DNS server */ - nm_setting_ip6_config_add_dns (s_ip6, &dns6); + nm_setting_ip_config_add_dns (s_ip6, dns6); ASSERT (nm_connection_verify (connection, &error) == TRUE, "wired-static-ip6-only-write", "failed to verify connection: %s", @@ -7231,13 +6726,12 @@ test_write_wired_static_ip6_only (void) "wired-static-ip6-only-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -7282,44 +6776,28 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + static const char *mac = "31:33:33:37:be:cd"; char *uuid; - struct in6_addr ip6; - struct in6_addr dns6; - NMIP6Address *addr6; + const char *dns6 = "fade:0102:0103::face"; + NMIPAddress *addr6; gboolean success; GError *error = NULL; char *testfile = NULL; char *id = NULL; gboolean ignore_error = FALSE; char *written_ifcfg_gateway; - char s_gateway6[INET6_ADDRSTRLEN] = { 0 }; - struct in6_addr gateway6_autovar; - const struct in6_addr *gateway6 = NULL; - - /* parsing the input argument and set the struct in6_addr "gateway6" to - * the gateway address. NULL means "do not set the gateway explicitly". */ - if (user_data) { - g_assert_cmpint (inet_pton (AF_INET6, user_data, &gateway6_autovar), ==, 1); - gateway6 = &gateway6_autovar; - } + const char *gateway6 = user_data; - inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6); - inet_pton (AF_INET6, "fade:0102:0103::face", &dns6); - if (gateway6) - inet_ntop (AF_INET6, gateway6, s_gateway6, sizeof (s_gateway6)); - - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); - id = g_strdup_printf ("Test Write Wired Static IP6 Only With Gateway %s", gateway6 ? s_gateway6 : "NULL"); + id = g_strdup_printf ("Test Write Wired Static IP6 Only With Gateway %s", gateway6 ? gateway6 : "NULL"); g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NM_SETTING_CONNECTION_UUID, uuid, @@ -7333,38 +6811,33 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, gateway6, NULL); /* Add addresses */ - addr6 = nm_ip6_address_new (); - nm_ip6_address_set_address (addr6, &ip6); - nm_ip6_address_set_prefix (addr6, 11); - if (gateway6) - nm_ip6_address_set_gateway (addr6, gateway6); - nm_setting_ip6_config_add_address (s_ip6, addr6); - nm_ip6_address_unref (addr6); + addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip6, addr6); + nm_ip_address_unref (addr6); /* DNS server */ - nm_setting_ip6_config_add_dns (s_ip6, &dns6); + nm_setting_ip_config_add_dns (s_ip6, dns6); g_assert (nm_connection_verify (connection, &error)); @@ -7378,13 +6851,13 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) g_assert (testfile); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, &error, &ignore_error); @@ -7407,18 +6880,18 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data) /* access the gateway from the loaded connection. */ s_ip6 = nm_connection_get_setting_ip6_config (reread); - g_assert (s_ip6 && nm_setting_ip6_config_get_num_addresses (s_ip6)==1); - addr6 = nm_setting_ip6_config_get_address (s_ip6, 0); + g_assert (s_ip6 && nm_setting_ip_config_get_num_addresses (s_ip6)==1); + addr6 = nm_setting_ip_config_get_address (s_ip6, 0); g_assert (addr6); /* assert that the gateway was written and reloaded as expected */ - if (!gateway6 || IN6_IS_ADDR_UNSPECIFIED (gateway6)) { - g_assert (IN6_IS_ADDR_UNSPECIFIED (nm_ip6_address_get_gateway (addr6))); - g_assert (written_ifcfg_gateway==NULL); + if (!gateway6 || !strcmp (gateway6, "::")) { + g_assert (nm_setting_ip_config_get_gateway (s_ip6) == NULL); + g_assert (written_ifcfg_gateway == NULL); } else { - g_assert (!IN6_IS_ADDR_UNSPECIFIED (nm_ip6_address_get_gateway (addr6))); - g_assert_cmpint (memcmp (nm_ip6_address_get_gateway (addr6), gateway6, sizeof (struct in6_addr)), ==, 0); - g_assert_cmpstr (written_ifcfg_gateway, ==, s_gateway6); + g_assert (nm_setting_ip_config_get_gateway (s_ip6) != NULL); + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, gateway6); + g_assert_cmpstr (written_ifcfg_gateway, ==, gateway6); } g_free (testfile); @@ -7435,7 +6908,7 @@ test_read_write_static_routes_legacy (void) NMConnection *connection, *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; char *testfile = NULL; char *keyfile = NULL; @@ -7452,7 +6925,6 @@ test_read_write_static_routes_legacy (void) connection = connection_from_file (TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -7507,18 +6979,18 @@ test_read_write_static_routes_legacy (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, + ASSERT (nm_setting_ip_config_get_never_default (s_ip4) == FALSE, "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT); /* Save the ifcfg; use a special different scratch dir to ensure that * we can clean up after the written connection in both the original @@ -7536,13 +7008,12 @@ test_read_write_static_routes_legacy (void) "read-write-static-routes-legacy-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile2, &routefile2, @@ -7584,26 +7055,17 @@ test_write_wired_static_routes (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + static const char *mac = "31:33:33:37:be:cd"; guint32 mtu = 1492; char *uuid; - const guint32 ip1 = htonl (0x01010103); - const guint32 ip2 = htonl (0x01010105); - const guint32 gw = htonl (0x01010101); - const guint32 dns1 = htonl (0x04020201); - const guint32 dns2 = htonl (0x04020202); - const guint32 route_dst1 = htonl (0x01020300); - const guint32 route_dst2= htonl (0x03020100); - const guint32 route_gw1 = htonl (0xdeadbeef); - const guint32 route_gw2 = htonl (0xcafeabbe); - const guint32 prefix = 24; + const char *dns1 = "4.2.2.1"; + const char *dns2 = "4.2.2.2"; const char *dns_search1 = "foobar.com"; const char *dns_search2 = "lab.foobar.com"; - NMIP4Address *addr; - NMIP4Route *route; + NMIPAddress *addr; + NMIPRoute *route; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -7613,7 +7075,7 @@ test_write_wired_static_routes (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -7632,66 +7094,54 @@ test_write_wired_static_routes (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", NULL); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip2); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); /* Write out routes */ - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, route_dst1); - nm_ip4_route_set_prefix (route, prefix); - nm_ip4_route_set_next_hop (route, route_gw1); - nm_setting_ip4_config_add_route (s_ip4, route); - nm_ip4_route_unref (route); - - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, route_dst2); - nm_ip4_route_set_prefix (route, prefix); - nm_ip4_route_set_next_hop (route, route_gw2); - nm_ip4_route_set_metric (route, 77); - nm_setting_ip4_config_add_route (s_ip4, route); - nm_ip4_route_unref (route); - - nm_setting_ip4_config_add_dns (s_ip4, dns1); - nm_setting_ip4_config_add_dns (s_ip4, dns2); - - nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1); - nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2); + route = nm_ip_route_new (AF_INET, "1.2.3.0", 24, "222.173.190.239", 0, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_route (s_ip4, route); + nm_ip_route_unref (route); + + route = nm_ip_route_new (AF_INET, "3.2.1.0", 24, "202.254.186.190", 77, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_route (s_ip4, route); + nm_ip_route_unref (route); + + nm_setting_ip_config_add_dns (s_ip4, dns1); + nm_setting_ip_config_add_dns (s_ip4, dns2); + + nm_setting_ip_config_add_dns_search (s_ip4, dns_search1); + nm_setting_ip_config_add_dns_search (s_ip4, dns_search2); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -7711,13 +7161,12 @@ test_write_wired_static_routes (void) "wired-static-routes-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -7755,8 +7204,8 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; NMSetting8021x *s_8021x; char *uuid; gboolean success; @@ -7768,7 +7217,7 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -7788,18 +7237,18 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* 802.1x setting */ @@ -7843,13 +7292,12 @@ test_write_wired_dhcp_8021x_peap_mschapv2 (void) "wired-dhcp-8021x-peap-mschapv2write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -7910,8 +7358,8 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; NMSetting8021x *s_8021x; char *uuid; gboolean success; @@ -7926,7 +7374,7 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, const char *pw; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection != NULL); /* Connection setting */ @@ -7949,17 +7397,17 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); @@ -8028,13 +7476,12 @@ test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme, g_assert (testfile != NULL); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -8125,14 +7572,12 @@ test_write_wired_aliases (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid; int num_addresses = 4; - guint32 ip[] = { 0x01010101, 0x01010102, 0x01010103, 0x01010104 }; + const char *ip[] = { "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" }; const char *label[] = { NULL, "alias0:2", NULL, "alias0:3" }; - const guint32 gw = htonl (0x01010101); - const guint32 prefix = 24; - NMIP4Address *addr; + NMIPAddress *addr; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -8144,7 +7589,7 @@ test_write_wired_aliases (void) shvarFile *ifcfg; int i, j; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); ASSERT (connection != NULL, "wired-aliases-write", "failed to allocate new connection"); @@ -8171,24 +7616,25 @@ test_write_wired_aliases (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); ASSERT (s_ip4 != NULL, "wired-aliases-write", "failed to allocate new %s setting", NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); for (i = 0; i < num_addresses; i++) { - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip[i]); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_add_address_with_label (s_ip4, addr, label[i])); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, ip[i], 24, &error); + g_assert_no_error (error); + if (label[i]) + nm_ip_address_set_attribute (addr, "label", g_variant_new_string (label[i])); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); } ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -8236,7 +7682,6 @@ test_write_wired_aliases (void) reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -8258,58 +7703,45 @@ test_write_wired_aliases (void) * verify the aliases manually. */ s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == num_addresses, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == num_addresses, "wired-aliases-write-verify-ip4", "failed to verify %s: unexpected %s / %s key value", testfile, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); /* Addresses */ for (i = 0; i < num_addresses; i++) { - guint32 addrbytes; + const char *addrstr; - addr = nm_setting_ip4_config_get_address (s_ip4, i); - ASSERT (addr, - "wired-aliases-write-verify-ip4", "failed to verify %s: missing IP4 address #%d", - testfile, - i); + addr = nm_setting_ip_config_get_address (s_ip4, i); + g_assert (addr != NULL); - addrbytes = nm_ip4_address_get_address (addr); + addrstr = nm_ip_address_get_address (addr); for (j = 0; j < num_addresses; j++) { - if (addrbytes == ip[j]) + if (!g_strcmp0 (addrstr, ip[j])) break; } + g_assert (j < num_addresses); - ASSERT (j < num_addresses, - "wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address #%d", - testfile, - i); + g_assert_cmpint (nm_ip_address_get_prefix (addr), ==, 24); + if (label[j]) + g_assert_cmpstr (g_variant_get_string (nm_ip_address_get_attribute (addr, "label"), NULL), ==, label[j]); + else + g_assert (nm_ip_address_get_attribute (addr, "label") == NULL); - ASSERT (nm_ip4_address_get_prefix (addr) == prefix, - "wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address prefix #%d", - testfile, - i); + ip[j] = NULL; + } - ASSERT (nm_ip4_address_get_gateway (addr) == gw, - "wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address gateway #%d", - testfile, - i); - - ASSERT (g_strcmp0 (NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)), label[j]) == 0, - "wired-aliases-write-verify-ip4", "failed to verify %s: unexpected IP4 address label #%d", - testfile, - i); - - ip[j] = 0; - } - - for (i = 0; i < num_addresses; i++) { - ASSERT (ip[i] == 0, - "wired-aliases-write-verify-ip4", "failed to verify %s: did not find IP4 address 0x%08x", + for (i = 0; i < num_addresses; i++) { + ASSERT (ip[i] == 0, + "wired-aliases-write-verify-ip4", "failed to verify %s: did not find IP4 address 0x%08x", testfile, ip[i]); } + /* Gateway */ + g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1"); + g_free (testfile); g_free (keyfile); g_free (routefile); @@ -8324,20 +7756,14 @@ test_write_gateway (void) NMConnection *connection, *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid, *testfile = NULL, *val; gboolean success; GError *error = NULL; shvarFile *f; - NMIP4Address *addr; - const char *ip1_str = "1.1.1.3"; - const char *ip2_str = "2.2.2.5"; - const char *gw1_str = "1.1.1.254"; - const char *gw2_str = "2.2.2.254"; - struct in_addr ip1, ip2, gw1, gw2; - const guint32 prefix = 24; + NMIPAddress *addr; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -8356,32 +7782,24 @@ test_write_gateway (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254", + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); - inet_pton (AF_INET, ip1_str, &ip1); - inet_pton (AF_INET, ip2_str, &ip2); - inet_pton (AF_INET, gw1_str, &gw1); - inet_pton (AF_INET, gw2_str, &gw2); - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1.s_addr); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw1.s_addr); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip2.s_addr); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw2.s_addr); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "2.2.2.5", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); success = nm_connection_verify (connection, &error); g_assert_no_error (error); @@ -8402,12 +7820,12 @@ test_write_gateway (void) /* re-read the file to check that the keys was written as IPADDR, GATEWAY and IPADDR1, GATEWAY1 */ val = svGetValue (f, "IPADDR", FALSE); g_assert (val); - g_assert_cmpstr (val, ==, ip1_str); + g_assert_cmpstr (val, ==, "1.1.1.3"); g_free (val); val = svGetValue (f, "IPADDR1", FALSE); g_assert (val); - g_assert_cmpstr (val, ==, ip2_str); + g_assert_cmpstr (val, ==, "2.2.2.5"); g_free (val); val = svGetValue (f, "IPADDR0", FALSE); @@ -8428,25 +7846,22 @@ test_write_gateway (void) val = svGetValue (f, "GATEWAY", FALSE); g_assert (val); - g_assert_cmpstr (val, ==, gw1_str); - g_free (val); - - val = svGetValue (f, "GATEWAY1", FALSE); - g_assert (val); - g_assert_cmpstr (val, ==, gw2_str); + g_assert_cmpstr (val, ==, "1.1.1.254"); g_free (val); val = svGetValue (f, "GATEWAY0", FALSE); g_assert (val == NULL); + val = svGetValue (f, "GATEWAY1", FALSE); + g_assert (val == NULL); svCloseFile (f); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL, + reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL, NULL, NULL, NULL, &error, NULL); unlink (testfile); g_assert_no_error (error); @@ -8471,8 +7886,8 @@ test_write_wifi_open (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -8482,17 +7897,15 @@ test_write_wifi_open (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - GByteArray *bssid; - const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + const char *bssid = "11:22:33:44:55:66"; guint32 channel = 9, mtu = 1345; - GByteArray *mac; - const unsigned char mac_data[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + const char *mac = "aa:bb:cc:dd:ee:ff"; shvarFile *ifcfg; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -8511,12 +7924,7 @@ test_write_wifi_open (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); - bssid = g_byte_array_sized_new (sizeof (bssid_data)); - g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); - mac = g_byte_array_sized_new (sizeof (mac_data)); - g_byte_array_append (mac, mac_data, sizeof (mac_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, @@ -8528,23 +7936,21 @@ test_write_wifi_open (void) NM_SETTING_WIRELESS_MTU, mtu, NULL); - g_byte_array_free (ssid, TRUE); - g_byte_array_free (bssid, TRUE); - g_byte_array_free (mac, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -8564,13 +7970,12 @@ test_write_wifi_open (void) "wifi-open-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -8621,8 +8026,8 @@ test_write_wifi_open_hex_ssid (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -8632,10 +8037,10 @@ test_write_wifi_open_hex_ssid (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd }; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -8654,29 +8059,28 @@ test_write_wifi_open_hex_ssid (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -8696,13 +8100,12 @@ test_write_wifi_open_hex_ssid (void) "wifi-open-hex-ssid-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -8737,8 +8140,8 @@ test_write_wifi_wep (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -8748,11 +8151,11 @@ test_write_wifi_wep (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; struct stat statbuf; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -8771,15 +8174,14 @@ test_write_wifi_wep (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -8796,18 +8198,18 @@ test_write_wifi_wep (void) nm_setting_wireless_security_set_wep_key (s_wsec, 3, "BBBBBBBBBBBBBBBBBBBBBBBBBB"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -8827,13 +8229,12 @@ test_write_wifi_wep (void) "wifi-wep-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -8880,8 +8281,8 @@ test_write_wifi_wep_adhoc (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -8891,16 +8292,13 @@ test_write_wifi_wep_adhoc (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; struct stat statbuf; - NMIP4Address *addr; - const guint32 ip1 = htonl (0x01010103); - const guint32 gw = htonl (0x01010101); - const guint32 dns1 = htonl (0x04020201); - const guint32 prefix = 24; + NMIPAddress *addr; + const char *dns1 = "4.2.2.1"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -8919,15 +8317,14 @@ test_write_wifi_wep_adhoc (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "adhoc", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -8937,28 +8334,29 @@ test_write_wifi_wep_adhoc (void) nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NULL); /* IP Address */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - nm_setting_ip4_config_add_dns (s_ip4, dns1); + nm_setting_ip_config_add_dns (s_ip4, dns1); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -8978,13 +8376,12 @@ test_write_wifi_wep_adhoc (void) "wifi-wep-adhoc-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9031,8 +8428,8 @@ test_write_wifi_wep_passphrase (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9042,11 +8439,11 @@ test_write_wifi_wep_passphrase (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; struct stat statbuf; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9065,15 +8462,14 @@ test_write_wifi_wep_passphrase (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9088,18 +8484,18 @@ test_write_wifi_wep_passphrase (void) nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9119,13 +8515,12 @@ test_write_wifi_wep_passphrase (void) "wifi-wep-passphrase-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9172,8 +8567,8 @@ test_write_wifi_wep_40_ascii (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9183,11 +8578,11 @@ test_write_wifi_wep_40_ascii (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah40"; + GBytes *ssid; + const char *ssid_data = "blahblah40"; struct stat statbuf; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9206,15 +8601,14 @@ test_write_wifi_wep_40_ascii (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9231,18 +8625,18 @@ test_write_wifi_wep_40_ascii (void) nm_setting_wireless_security_set_wep_key (s_wsec, 3, "donec"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9262,13 +8656,12 @@ test_write_wifi_wep_40_ascii (void) "wifi-wep-40-ascii-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9315,8 +8708,8 @@ test_write_wifi_wep_104_ascii (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9326,11 +8719,11 @@ test_write_wifi_wep_104_ascii (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah104"; + GBytes *ssid; + const char *ssid_data = "blahblah104"; struct stat statbuf; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9349,15 +8742,14 @@ test_write_wifi_wep_104_ascii (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9374,18 +8766,18 @@ test_write_wifi_wep_104_ascii (void) nm_setting_wireless_security_set_wep_key (s_wsec, 3, "thisismyascii"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9405,13 +8797,12 @@ test_write_wifi_wep_104_ascii (void) "wifi-wep-104-ascii-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9458,8 +8849,8 @@ test_write_wifi_leap (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9469,11 +8860,11 @@ test_write_wifi_leap (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; struct stat statbuf; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9492,15 +8883,14 @@ test_write_wifi_leap (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9514,18 +8904,18 @@ test_write_wifi_leap (void) NULL); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9545,13 +8935,12 @@ test_write_wifi_leap (void) "wifi-leap-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9598,8 +8987,8 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9609,10 +8998,10 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -9633,13 +9022,12 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9655,19 +9043,19 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) NULL); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); success = nm_connection_verify (connection, &error); @@ -9684,13 +9072,12 @@ test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags) g_assert (testfile); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9739,8 +9126,8 @@ test_write_wifi_wpa_psk (const char *name, NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid, *tmp; gboolean success; GError *error = NULL; @@ -9750,12 +9137,12 @@ test_write_wifi_wpa_psk (const char *name, char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; g_return_if_fail (psk != NULL); - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9774,15 +9161,14 @@ test_write_wifi_wpa_psk (const char *name, s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9809,18 +9195,18 @@ test_write_wifi_wpa_psk (const char *name, } /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9840,13 +9226,12 @@ test_write_wifi_wpa_psk (const char *name, test_name, "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -9887,8 +9272,8 @@ test_write_wifi_wpa_psk_adhoc (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -9898,15 +9283,12 @@ test_write_wifi_wpa_psk_adhoc (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; - NMIP4Address *addr; - const guint32 ip1 = htonl (0x01010103); - const guint32 gw = htonl (0x01010101); - const guint32 dns1 = htonl (0x04020201); - const guint32 prefix = 24; + GBytes *ssid; + const char *ssid_data = "blahblah"; + NMIPAddress *addr; + const char *dns1 = "4.2.2.1"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -9925,8 +9307,7 @@ test_write_wifi_wpa_psk_adhoc (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, @@ -9935,7 +9316,7 @@ test_write_wifi_wpa_psk_adhoc (void) NM_SETTING_WIRELESS_BAND, "bg", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -9950,28 +9331,29 @@ test_write_wifi_wpa_psk_adhoc (void) nm_setting_wireless_security_add_group (s_wsec, "tkip"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NULL); /* IP Address */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 25, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); - nm_setting_ip4_config_add_dns (s_ip4, dns1); + nm_setting_ip_config_add_dns (s_ip4, dns1); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -9991,13 +9373,12 @@ test_write_wifi_wpa_psk_adhoc (void) "wifi-wpa-psk-adhoc-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10037,8 +9418,8 @@ test_write_wifi_wpa_eap_tls (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10048,10 +9429,10 @@ test_write_wifi_wpa_eap_tls (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const char *ssid_data = "blahblah"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -10070,15 +9451,14 @@ test_write_wifi_wpa_eap_tls (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (strlen (ssid_data)); - g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -10126,18 +9506,18 @@ test_write_wifi_wpa_eap_tls (void) TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -10157,13 +9537,12 @@ test_write_wifi_wpa_eap_tls (void) "wifi-wpa-eap-tls-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10203,8 +9582,8 @@ test_write_wifi_wpa_eap_ttls_tls (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10214,10 +9593,10 @@ test_write_wifi_wpa_eap_ttls_tls (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const char *ssid_data = "blahblah"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -10236,15 +9615,14 @@ test_write_wifi_wpa_eap_ttls_tls (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (strlen (ssid_data)); - g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -10310,18 +9688,18 @@ test_write_wifi_wpa_eap_ttls_tls (void) TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -10341,13 +9719,12 @@ test_write_wifi_wpa_eap_ttls_tls (void) "wifi-wpa-eap-ttls-tls-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10387,8 +9764,8 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10398,10 +9775,10 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const char *ssid_data = "blahblah"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -10420,15 +9797,14 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (strlen (ssid_data)); - g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -10466,18 +9842,18 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -10497,13 +9873,12 @@ test_write_wifi_wpa_eap_ttls_mschapv2 (void) "wifi-wpa-eap-ttls-mschapv2-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10542,8 +9917,8 @@ test_write_wifi_wpa_then_open (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10553,14 +9928,14 @@ test_write_wifi_wpa_then_open (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - const unsigned char ssid_data[] = "blahblah"; + GBytes *ssid; + const char *ssid_data = "blahblah"; /* Test that writing out a WPA config then changing that to an open * config doesn't leave various WPA-related keys lying around in the ifcfg. */ - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -10582,15 +9957,14 @@ test_write_wifi_wpa_then_open (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -10611,20 +9985,20 @@ test_write_wifi_wpa_then_open (void) nm_setting_wireless_security_add_group (s_wsec, "ccmp"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); success = nm_connection_verify (connection, &error); @@ -10641,13 +10015,12 @@ test_write_wifi_wpa_then_open (void) g_assert (testfile); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10688,13 +10061,12 @@ test_write_wifi_wpa_then_open (void) keyfile = NULL; /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read it for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10735,8 +10107,8 @@ test_write_wifi_wpa_then_wep_with_perms (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10746,15 +10118,15 @@ test_write_wifi_wpa_then_wep_with_perms (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; - GSList *perm_list = NULL; - const unsigned char ssid_data[] = "SomeSSID"; + GBytes *ssid; + char **perms; + const char *ssid_data = "SomeSSID"; /* Test that writing out a WPA config then changing that to a WEP * config works and doesn't cause infinite loop or other issues. */ - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -10763,16 +10135,16 @@ test_write_wifi_wpa_then_wep_with_perms (void) nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); - perm_list = g_slist_append (perm_list, "user:superman:"); + perms = g_strsplit ("user:superman:", ",", -1); g_object_set (s_con, NM_SETTING_CONNECTION_ID, "random wifi connection 2", NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_PERMISSIONS, perm_list, + NM_SETTING_CONNECTION_PERMISSIONS, perms, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, NULL); g_free (uuid); - g_slist_free (perm_list); + g_strfreev (perms); ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, "test_write_wifi_wpa_then_wep_with_perms", "unexpected failure adding valid user permisson"); @@ -10781,15 +10153,14 @@ test_write_wifi_wpa_then_wep_with_perms (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wireless security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -10810,20 +10181,20 @@ test_write_wifi_wpa_then_wep_with_perms (void) nm_setting_wireless_security_add_group (s_wsec, "ccmp"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); success = nm_connection_verify (connection, &error); @@ -10840,13 +10211,12 @@ test_write_wifi_wpa_then_wep_with_perms (void) g_assert (testfile); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10893,13 +10263,12 @@ test_write_wifi_wpa_then_wep_with_perms (void) keyfile = NULL; /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read it for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -10942,8 +10311,8 @@ test_write_wifi_dynamic_wep_leap (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -10953,12 +10322,12 @@ test_write_wifi_dynamic_wep_leap (void) char *routefile = NULL; char *route6file = NULL; gboolean ignore_error = FALSE; - GByteArray *ssid; + GBytes *ssid; const char *ssid_data = "blahblah"; shvarFile *ifcfg; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -10966,521 +10335,126 @@ test_write_wifi_dynamic_wep_leap (void) g_assert (s_con); nm_connection_add_setting (connection, NM_SETTING (s_con)); - uuid = nm_utils_uuid_generate (); - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP", - NM_SETTING_CONNECTION_UUID, uuid, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - g_free (uuid); - - /* Wifi setting */ - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - g_assert (s_wifi); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - - ssid = g_byte_array_sized_new (strlen (ssid_data)); - g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data)); - - g_object_set (s_wifi, - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, "infrastructure", - NULL); - - g_byte_array_free (ssid, TRUE); - - /* Wireless security setting */ - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - g_assert (s_wsec); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - - g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); - - /* Wireless security setting */ - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - g_assert (s_8021x); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - - nm_setting_802_1x_add_eap_method (s_8021x, "leap"); - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", - NULL); - - /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - g_assert (s_ip4); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - g_assert (s_ip6); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, - NULL); - - success = nm_connection_verify (connection, &error); - g_assert_no_error (error); - g_assert (success); - - /* Save the ifcfg */ - success = writer_new_connection (connection, - TEST_SCRATCH_DIR "/network-scripts/", - &testfile, - &error); - g_assert_no_error (error); - g_assert (success); - g_assert (testfile); - - /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); - - /* re-read the connection for comparison */ - reread = connection_from_file (testfile, - NULL, - TYPE_WIRELESS, - NULL, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - g_assert_no_error (error); - g_assert (reread); - g_assert (keyfile); - unlink (keyfile); - - success = nm_connection_verify (reread, &error); - g_assert_no_error (error); - g_assert (success); - - success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); - g_assert (success); - - /* Check and make sure that an "old-school" LEAP (Network EAP) connection - * did not get written. Check first that the auth alg is not set to "LEAP" - * and next that the only IEEE 802.1x EAP method is "LEAP". - */ - ifcfg = svOpenFile (testfile, &error); - g_assert_no_error (error); - g_assert (ifcfg); - tmp = svGetValue (ifcfg, "SECURITYMODE", FALSE); - g_assert_cmpstr (tmp, ==, NULL); - g_free (tmp); - - tmp = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE); - g_assert_cmpstr (tmp, ==, "LEAP"); - g_free (tmp); - - svCloseFile (ifcfg); - unlink (testfile); - - g_free (testfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); - g_object_unref (connection); - g_object_unref (reread); -} - -#define TEST_IFCFG_IBFT_DHCP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-dhcp" - -static void -test_read_ibft_dhcp (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - const char *tmp; - const GByteArray *array; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf1 }; - const char *expected_id = "System test-ibft-dhcp"; - guint64 expected_timestamp = 0; - - connection = connection_from_file (TEST_IFCFG_IBFT_DHCP, - NULL, - TYPE_ETHERNET, - TEST_IFCFG_DIR "/iscsiadm-test-dhcp", - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - ASSERT (connection != NULL, - "ibft-dhcp-read", "failed to read %s: %s", TEST_IFCFG_IBFT_DHCP, error->message); - - ASSERT (nm_connection_verify (connection, &error), - "ibft-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_DHCP, error->message); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - ASSERT (s_con != NULL, - "ibft-dhcp-verify-connection", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME); - - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - ASSERT (tmp != NULL, - "ibft-dhcp-verify-connection", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - ASSERT (strcmp (tmp, expected_id) == 0, - "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ - - /* Timestamp */ - ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, - "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP); - - /* Autoconnect */ - ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, - "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_AUTOCONNECT); - - /* Read-only */ - ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE, - "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_READ_ONLY); - - /* ===== WIRED SETTING ===== */ - - s_wired = nm_connection_get_setting_wired (connection); - ASSERT (s_wired != NULL, - "ibft-dhcp-verify-wired", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_WIRED_SETTING_NAME); - - /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array != NULL, - "ibft-dhcp-verify-wired", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, - "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - - ASSERT (nm_setting_wired_get_mtu (s_wired) == 0, - "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MTU); - - /* ===== IPv4 SETTING ===== */ - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (s_ip4 != NULL, - "ibft-dhcp-verify-ip4", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_IP4_CONFIG_SETTING_NAME); - - /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, - "ibft-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_DHCP, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); - - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); - g_object_unref (connection); -} - -#define TEST_IFCFG_IBFT_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-static" - -static void -test_read_ibft_static (void) -{ - NMConnection *connection; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; - const char *tmp; - const GByteArray *array; - char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf0 }; - const char *expected_id = "System test-ibft-static"; - guint64 expected_timestamp = 0; - const char *expected_dns1 = "10.16.255.2"; - const char *expected_dns2 = "10.16.255.3"; - guint32 addr; - const char *expected_address1 = "192.168.32.72"; - const char *expected_address1_gw = "192.168.35.254"; - NMIP4Address *ip4_addr; - - connection = connection_from_file (TEST_IFCFG_IBFT_STATIC, - NULL, - TYPE_ETHERNET, - TEST_IFCFG_DIR "/iscsiadm-test-static", - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - ASSERT (connection != NULL, - "ibft-static-read", "failed to read %s: %s", TEST_IFCFG_IBFT_STATIC, error->message); - - ASSERT (nm_connection_verify (connection, &error), - "ibft-static-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_STATIC, error->message); - - /* ===== CONNECTION SETTING ===== */ - - s_con = nm_connection_get_setting_connection (connection); - ASSERT (s_con != NULL, - "ibft-static-verify-connection", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME); - - /* ID */ - tmp = nm_setting_connection_get_id (s_con); - ASSERT (tmp != NULL, - "ibft-static-verify-connection", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - ASSERT (strcmp (tmp, expected_id) == 0, - "ibft-static-verify-connection", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_ID); - - /* UUID can't be tested if the ifcfg does not contain the UUID key, because - * the UUID is generated on the full path of the ifcfg file, which can change - * depending on where the tests are run. - */ - - /* Timestamp */ - ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp, - "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_TIMESTAMP); - - /* Autoconnect */ - ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE, - "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_AUTOCONNECT); + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); - /* Read-only */ - ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE, - "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_CONNECTION_SETTING_NAME, - NM_SETTING_CONNECTION_READ_ONLY); + /* Wifi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + g_assert (s_wifi); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - /* ===== WIRED SETTING ===== */ + ssid = g_bytes_new (ssid_data, strlen (ssid_data)); - s_wired = nm_connection_get_setting_wired (connection); - ASSERT (s_wired != NULL, - "ibft-static-verify-wired", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_WIRED_SETTING_NAME); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, "infrastructure", + NULL); - /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array != NULL, - "ibft-static-verify-wired", "failed to verify %s: missing %s / %s key", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, - "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); + g_bytes_unref (ssid); - ASSERT (nm_setting_wired_get_mtu (s_wired) == 0, - "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MTU); + /* Wireless security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_assert (s_wsec); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - /* ===== IPv4 SETTING ===== */ + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); - s_ip4 = nm_connection_get_setting_ip4_config (connection); - ASSERT (s_ip4 != NULL, - "ibft-static-verify-ip4", "failed to verify %s: missing %s setting", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME); + /* Wireless security setting */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + g_assert (s_8021x); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); - ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, - "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + nm_setting_802_1x_add_eap_method (s_8021x, "leap"); - /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, - "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + g_object_set (s_8021x, + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf", + NULL); - ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, - "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, - "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, - "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, - "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, - "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NULL); - /* Address #1 */ - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - "ibft-static-verify-ip4", "failed to verify %s: missing IP4 address #1", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 22, - "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); - ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0, - "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + /* reread will be normalized, so we must normalize connection too. */ + nm_connection_normalize (connection, NULL, NULL, NULL); - ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0, - "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); - ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr, - "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway", - TEST_IFCFG_IBFT_STATIC, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_WIRELESS, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + g_assert_no_error (error); + g_assert (reread); + g_assert (keyfile); + unlink (keyfile); - g_free (unmanaged); - g_free (keyfile); - g_free (routefile); - g_free (route6file); - g_object_unref (connection); -} + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); -static void -test_read_ibft_malformed (const char *name, const char *iscsiadm_path, gboolean expect_warning) -{ - NMConnection *connection; - char *unmanaged = NULL; - char *keyfile = NULL; - char *routefile = NULL; - char *route6file = NULL; - gboolean ignore_error = FALSE; - GError *error = NULL; + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + /* Check and make sure that an "old-school" LEAP (Network EAP) connection + * did not get written. Check first that the auth alg is not set to "LEAP" + * and next that the only IEEE 802.1x EAP method is "LEAP". + */ + ifcfg = svOpenFile (testfile, &error); + g_assert_no_error (error); + g_assert (ifcfg); + tmp = svGetValue (ifcfg, "SECURITYMODE", FALSE); + g_assert_cmpstr (tmp, ==, NULL); + g_free (tmp); - g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS)); + tmp = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE); + g_assert_cmpstr (tmp, ==, "LEAP"); + g_free (tmp); - if (expect_warning) { - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*malformed iscsiadm record*"); - } - connection = connection_from_file (TEST_IFCFG_IBFT_STATIC, - NULL, - TYPE_ETHERNET, - iscsiadm_path, - &unmanaged, - &keyfile, - &routefile, - &route6file, - &error, - &ignore_error); - if (expect_warning) - g_test_assert_expected_messages (); - ASSERT (connection == NULL, - name, "unexpectedly able to read %s", TEST_IFCFG_IBFT_STATIC); + svCloseFile (ifcfg); + unlink (testfile); + g_free (testfile); g_free (unmanaged); g_free (keyfile); g_free (routefile); g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); } static void @@ -11490,10 +10464,10 @@ test_write_wired_qeth_dhcp (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - GPtrArray *subchans; + char **subchans; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -11503,7 +10477,7 @@ test_write_wired_qeth_dhcp (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -11522,15 +10496,12 @@ test_write_wired_qeth_dhcp (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - subchans = g_ptr_array_sized_new (3); - g_ptr_array_add (subchans, "0.0.600"); - g_ptr_array_add (subchans, "0.0.601"); - g_ptr_array_add (subchans, "0.0.602"); + subchans = g_strsplit ("0.0.600,0.0.601,0.0.602", ",", -1); g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, NM_SETTING_WIRED_S390_NETTYPE, "qeth", NULL); - g_ptr_array_free (subchans, TRUE); + g_strfreev (subchans); nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR"); nm_setting_wired_add_s390_option (s_wired, "portno", "1"); @@ -11538,20 +10509,20 @@ test_write_wired_qeth_dhcp (void) nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Verify */ @@ -11572,13 +10543,12 @@ test_write_wired_qeth_dhcp (void) "wired-qeth-dhcp-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -11615,10 +10585,10 @@ test_write_wired_ctc_dhcp (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - GPtrArray *subchans; + char **subchans; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -11630,7 +10600,7 @@ test_write_wired_ctc_dhcp (void) shvarFile *ifcfg; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -11651,30 +10621,28 @@ test_write_wired_ctc_dhcp (void) g_assert (s_wired); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - subchans = g_ptr_array_sized_new (2); - g_ptr_array_add (subchans, "0.0.600"); - g_ptr_array_add (subchans, "0.0.601"); + subchans = g_strsplit ("0.0.600,0.0.601", ",", -1); g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchans, NM_SETTING_WIRED_S390_NETTYPE, "ctc", NULL); - g_ptr_array_free (subchans, TRUE); + g_strfreev (subchans); nm_setting_wired_add_s390_option (s_wired, "ctcprot", "0"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Verify */ @@ -11709,13 +10677,12 @@ test_write_wired_ctc_dhcp (void) svCloseFile (ifcfg); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -11751,8 +10718,8 @@ test_write_permissions (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -11763,7 +10730,7 @@ test_write_permissions (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -11787,20 +10754,20 @@ test_write_permissions (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Verify */ @@ -11821,13 +10788,12 @@ test_write_permissions (void) "permissions-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -11865,11 +10831,11 @@ test_write_wifi_wep_agent_keys (void) NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; const char *str_ssid = "foobarbaz"; - GByteArray *ssid; + GBytes *ssid; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -11879,7 +10845,7 @@ test_write_wifi_wep_agent_keys (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection != NULL); /* Connection setting */ @@ -11896,19 +10862,19 @@ test_write_wifi_wep_agent_keys (void) g_free (uuid); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); /* Wifi setting */ @@ -11916,13 +10882,12 @@ test_write_wifi_wep_agent_keys (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (strlen (str_ssid)); - g_byte_array_append (ssid, (guint8 *) str_ssid, strlen (str_ssid)); + ssid = g_bytes_new (str_ssid, strlen (str_ssid)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* Wifi security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -11951,13 +10916,12 @@ test_write_wifi_wep_agent_keys (void) g_assert (testfile != NULL); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_WIRELESS, - NULL, &unmanaged, &keyfile, &routefile, @@ -12005,15 +10969,15 @@ test_write_wired_pppoe (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingPPPOE *s_pppoe; - NMSettingPPP *s_ppp; + NMSettingIPConfig *s_ip4; + NMSettingPppoe *s_pppoe; + NMSettingPpp *s_ppp; char *uuid; gboolean success; GError *error = NULL; char *testfile = NULL; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -12033,15 +10997,15 @@ test_write_wired_pppoe (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* PPPoE setting */ - s_pppoe = (NMSettingPPPOE *) nm_setting_pppoe_new (); + s_pppoe = (NMSettingPppoe *) nm_setting_pppoe_new (); nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); g_object_set (G_OBJECT (s_pppoe), @@ -12051,7 +11015,7 @@ test_write_wired_pppoe (void) NULL); /* PPP setting */ - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); nm_connection_add_setting (connection, NM_SETTING (s_ppp)); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -12074,14 +11038,14 @@ test_write_vpn (void) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; - NMSettingVPN *s_vpn; + NMSettingIPConfig *s_ip4; + NMSettingVpn *s_vpn; char *uuid; gboolean success; GError *error = NULL; char *testfile = NULL; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -12097,7 +11061,7 @@ test_write_vpn (void) g_free (uuid); /* VPN setting */ - s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); + s_vpn = (NMSettingVpn *) nm_setting_vpn_new (); nm_connection_add_setting (connection, NM_SETTING (s_vpn)); g_object_set (s_vpn, @@ -12109,11 +11073,11 @@ test_write_vpn (void) nm_setting_vpn_add_secret (s_vpn, "password", "sup3rs3cr3t"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -12136,17 +11100,17 @@ test_write_mobile_broadband (gboolean gsm) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSettingGsm *s_gsm; NMSettingCdma *s_cdma; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; NMSettingSerial *s_serial; char *uuid; gboolean success; GError *error = NULL; char *testfile = NULL; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -12182,20 +11146,20 @@ test_write_mobile_broadband (gboolean gsm) g_object_set (s_serial, NM_SETTING_SERIAL_BAUD, 115200, NM_SETTING_SERIAL_BITS, 8, - NM_SETTING_SERIAL_PARITY, 'n', + NM_SETTING_SERIAL_PARITY, NM_SETTING_SERIAL_PARITY_NONE, NM_SETTING_SERIAL_STOPBITS, 1, NULL); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* PPP setting */ - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); nm_connection_add_setting (connection, NM_SETTING (s_ppp)); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -12220,7 +11184,7 @@ test_read_bridge_main (void) { NMConnection *connection; NMSettingBridge *s_bridge; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 }; char *unmanaged = NULL; char *keyfile = NULL; @@ -12232,7 +11196,6 @@ test_read_bridge_main (void) connection = connection_from_file (TEST_IFCFG_BRIDGE_MAIN, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12243,22 +11206,23 @@ test_read_bridge_main (void) g_assert (nm_connection_verify (connection, &error)); g_assert_no_error (error); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "br0"); + /* ===== Bridging SETTING ===== */ s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); - g_assert_cmpstr (nm_setting_bridge_get_interface_name (s_bridge), ==, "br0"); g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 0); g_assert (nm_setting_bridge_get_stp (s_bridge)); g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7); g_assert_cmpuint (nm_setting_bridge_get_max_age (s_bridge), ==, 39); g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352); + /* MAC address */ - array = nm_setting_bridge_get_mac_address (s_bridge); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, &expected_mac_address[0], ETH_ALEN) == 0); + mac = nm_setting_bridge_get_mac_address (s_bridge); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, ETH_ALEN)); g_free (unmanaged); g_free (keyfile); @@ -12274,15 +11238,11 @@ test_write_bridge_main (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingBridge *s_bridge; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - const guint32 ip1 = htonl (0x01010103); - const guint32 gw = htonl (0x01010101); - const guint32 prefix = 24; - NMIP4Address *addr; - static unsigned char bridge_mac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac_array; + NMIPAddress *addr; + static const char *mac = "31:33:33:37:be:cd"; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -12292,7 +11252,7 @@ test_write_bridge_main (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -12305,6 +11265,7 @@ test_write_bridge_main (void) NM_SETTING_CONNECTION_ID, "Test Write Bridge Main", NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, "br0", NM_SETTING_CONNECTION_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, NULL); g_free (uuid); @@ -12314,42 +11275,36 @@ test_write_bridge_main (void) g_assert (s_bridge); nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - mac_array = g_byte_array_sized_new (sizeof (bridge_mac)); - g_byte_array_append (mac_array, bridge_mac, sizeof (bridge_mac)); g_object_set (s_bridge, - NM_SETTING_BRIDGE_INTERFACE_NAME, "br0", - NM_SETTING_BRIDGE_MAC_ADDRESS, mac_array, + NM_SETTING_BRIDGE_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac_array, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - g_assert (nm_connection_verify (connection, &error)); - g_assert_no_error (error); + nmtst_assert_connection_verifies_without_normalization (connection); /* Save the ifcfg */ success = writer_new_connection (connection, @@ -12360,13 +11315,12 @@ test_write_bridge_main (void) g_assert_cmpstr (testfile, !=, NULL); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_BRIDGE, - NULL, &unmanaged, &keyfile, &routefile, @@ -12408,7 +11362,6 @@ test_read_bridge_component (void) connection = connection_from_file (TEST_IFCFG_BRIDGE_COMPONENT, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12447,8 +11400,7 @@ test_write_bridge_component (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSetting *s_port; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + static const char *mac = "31:33:33:37:be:cd"; guint32 mtu = 1492; char *uuid; gboolean success; @@ -12460,7 +11412,7 @@ test_write_bridge_component (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -12484,14 +11436,10 @@ test_write_bridge_component (void) g_assert (s_wired); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_byte_array_free (mac, TRUE); /* Bridge port */ s_port = nm_setting_bridge_port_new (); @@ -12515,13 +11463,12 @@ test_write_bridge_component (void) g_assert (testfile); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12564,7 +11511,6 @@ test_read_bridge_missing_stp (void) connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-missing-stp", NULL, TYPE_BRIDGE, - NULL, &unmanaged, &keyfile, &routefile, @@ -12575,11 +11521,12 @@ test_read_bridge_missing_stp (void) g_assert (nm_connection_verify (connection, &error)); g_assert_no_error (error); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "br0"); + /* ===== Bridging SETTING ===== */ s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); - g_assert_cmpstr (nm_setting_bridge_get_interface_name (s_bridge), ==, "br0"); g_assert (nm_setting_bridge_get_stp (s_bridge) == FALSE); g_free (unmanaged); @@ -12607,7 +11554,6 @@ test_read_vlan_interface (void) connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12622,10 +11568,11 @@ test_read_vlan_interface (void) g_free (routefile); g_free (route6file); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan43"); + s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); - g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "vlan43"); g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, @@ -12677,7 +11624,6 @@ test_read_vlan_only_vlan_id (void) connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12692,10 +11638,11 @@ test_read_vlan_only_vlan_id (void) g_free (routefile); g_free (route6file); + g_assert (nm_connection_get_interface_name (connection) == NULL); + s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); - g_assert (nm_setting_vlan_get_interface_name (s_vlan) == NULL); g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 43); @@ -12719,7 +11666,6 @@ test_read_vlan_only_device (void) connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_DEVICE, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12734,10 +11680,11 @@ test_read_vlan_only_device (void) g_free (routefile); g_free (route6file); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0.9"); + s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); - g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "eth0.9"); g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 9); @@ -12752,16 +11699,17 @@ test_read_vlan_physdev (void) NMSettingVlan *s_vlan; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-physdev", - NULL, TYPE_ETHERNET, NULL, NULL, + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); g_assert (nm_connection_verify (connection, &error)); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan0.3"); + s_vlan = nm_connection_get_setting_vlan (connection); g_assert (s_vlan); - g_assert_cmpstr (nm_setting_vlan_get_interface_name (s_vlan), ==, "vlan0.3"); g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth0"); g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 3); @@ -12784,7 +11732,6 @@ test_write_vlan (void) connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE, NULL, TYPE_VLAN, - NULL, &unmanaged, &keyfile, &routefile, @@ -12824,7 +11771,6 @@ test_write_vlan_only_vlanid (void) connection = connection_from_file (TEST_IFCFG_VLAN_ONLY_VLANID, NULL, TYPE_VLAN, - NULL, &unmanaged, &keyfile, &routefile, @@ -12850,13 +11796,12 @@ test_write_vlan_only_vlanid (void) g_assert (success); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (written, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12891,8 +11836,8 @@ test_write_ethernet_missing_ipv6 (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; GError *error = NULL; @@ -12903,7 +11848,7 @@ test_write_ethernet_missing_ipv6 (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -12926,14 +11871,14 @@ test_write_ethernet_missing_ipv6 (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33", - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, TRUE, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); /* IP6 setting */ @@ -12959,13 +11904,12 @@ test_write_ethernet_missing_ipv6 (void) "ethernet-missing-ipv6", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -12985,12 +11929,12 @@ test_write_ethernet_missing_ipv6 (void) * the comparison can succeed. Missing IPv6 setting should have been * written out (and re-read) as Automatic IPv6. */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -13005,6 +11949,19 @@ test_write_ethernet_missing_ipv6 (void) g_object_unref (reread); } +static void +test_read_ibft_ignored (void) +{ + NMConnection *connection; + GError *error = NULL; + + connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft", + NULL, TYPE_ETHERNET, + NULL, NULL, NULL, NULL, &error, NULL); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); + g_assert (connection == NULL); +} + #define TEST_IFCFG_BOND_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bond-main" static void @@ -13022,7 +11979,6 @@ test_read_bond_main (void) connection = connection_from_file (TEST_IFCFG_BOND_MAIN, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -13035,6 +11991,10 @@ test_read_bond_main (void) ASSERT (nm_connection_verify (connection, &error), "bond-main-read", "failed to verify %s: %s", TEST_IFCFG_BOND_MAIN, error->message); + ASSERT (g_strcmp0 (nm_connection_get_interface_name (connection), "bond0") == 0, + "bond-main", "failed to verify %s: DEVICE=%s does not match bond0", + TEST_IFCFG_BOND_MAIN, nm_connection_get_interface_name (connection)); + /* ===== Bonding SETTING ===== */ s_bond = nm_connection_get_setting_bond (connection); @@ -13043,10 +12003,6 @@ test_read_bond_main (void) TEST_IFCFG_BOND_MAIN, NM_SETTING_BOND_SETTING_NAME); - ASSERT (g_strcmp0 (nm_setting_bond_get_interface_name (s_bond), "bond0") == 0, - "bond-main", "failed to verify %s: DEVICE=%s does not match bond0", - TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_interface_name (s_bond)); - ASSERT (g_strcmp0 (nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON), "100") == 0, "bond-main", "failed to verify %s: miimon=%s does not match 100", TEST_IFCFG_BOND_MAIN, nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON)); @@ -13065,14 +12021,11 @@ test_write_bond_main (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingBond *s_bond; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; NMSettingWired *s_wired; char *uuid; - const guint32 ip1 = htonl (0x01010103); - const guint32 gw = htonl (0x01010101); - const guint32 prefix = 24; - NMIP4Address *addr; + NMIPAddress *addr; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -13082,7 +12035,7 @@ test_write_bond_main (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -13093,6 +12046,7 @@ test_write_bond_main (void) NM_SETTING_CONNECTION_ID, "Test Write Bond Main", NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_INTERFACE_NAME, "bond0", NM_SETTING_CONNECTION_TYPE, NM_SETTING_BOND_SETTING_NAME, NULL); g_free (uuid); @@ -13105,37 +12059,30 @@ test_write_bond_main (void) s_bond = (NMSettingBond *) nm_setting_bond_new (); nm_connection_add_setting (connection, NM_SETTING (s_bond)); - g_object_set (s_bond, - NM_SETTING_BOND_INTERFACE_NAME, "bond0", - NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); - ASSERT (nm_connection_verify (connection, &error) == TRUE, - "bond-main-write", "failed to verify connection: %s", - (error && error->message) ? error->message : "(unknown)"); + nmtst_assert_connection_verifies_without_normalization (connection); /* Save the ifcfg */ success = writer_new_connection (connection, @@ -13150,13 +12097,12 @@ test_write_bond_main (void) "bond-main-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_BOND, - NULL, &unmanaged, &keyfile, &routefile, @@ -13197,12 +12143,9 @@ test_read_bond_slave (void) gboolean ignore_error = FALSE; GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring IP4 config on slave*"); connection = connection_from_file (TEST_IFCFG_BOND_SLAVE, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -13244,8 +12187,7 @@ test_write_bond_slave (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingWired *s_wired; - static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd }; - GByteArray *mac; + static const char *mac = "31:33:33:37:be:cd"; guint32 mtu = 1492; char *uuid; gboolean success; @@ -13257,7 +12199,7 @@ test_write_bond_slave (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -13278,14 +12220,10 @@ test_write_bond_slave (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, mtu, NULL); - g_byte_array_free (mac, TRUE); ASSERT (nm_connection_verify (connection, &error) == TRUE, "bond-slave-write", "failed to verify connection: %s", @@ -13304,13 +12242,12 @@ test_write_bond_slave (void) "bond-slave-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, &unmanaged, &keyfile, &routefile, @@ -13353,14 +12290,13 @@ test_read_infiniband (void) char *route6file = NULL; gboolean ignore_error = FALSE; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; const char *transport_mode; connection = connection_from_file (TEST_IFCFG_INFINIBAND, NULL, TYPE_INFINIBAND, - NULL, &unmanaged, &keyfile, &routefile, @@ -13385,18 +12321,13 @@ test_read_infiniband (void) NM_SETTING_INFINIBAND_SETTING_NAME); /* MAC address */ - array = nm_setting_infiniband_get_mac_address (s_infiniband); - ASSERT (array != NULL, + mac = nm_setting_infiniband_get_mac_address (s_infiniband); + ASSERT (mac != NULL, "infiniband-verify-infiniband", "failed to verify %s: missing %s / %s key", TEST_IFCFG_INFINIBAND, NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS); - ASSERT (array->len == INFINIBAND_ALEN, - "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value length", - TEST_IFCFG_INFINIBAND, - NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_INFINIBAND_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "infiniband-verify-infiniband", "failed to verify %s: unexpected %s / %s key value", TEST_IFCFG_INFINIBAND, NM_SETTING_INFINIBAND_SETTING_NAME, @@ -13429,16 +12360,12 @@ test_write_infiniband (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingInfiniband *s_infiniband; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - unsigned char tmpmac[INFINIBAND_ALEN] = { 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 }; - GByteArray *mac; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + const char *mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; guint32 mtu = 65520; char *uuid; - const guint32 ip1 = htonl (0x01010103); - const guint32 gw = htonl (0x01010101); - const guint32 prefix = 24; - NMIP4Address *addr; + NMIPAddress *addr; gboolean success; GError *error = NULL; char *testfile = NULL; @@ -13448,7 +12375,7 @@ test_write_infiniband (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -13467,38 +12394,33 @@ test_write_infiniband (void) s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NM_SETTING_INFINIBAND_MTU, mtu, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, ip1); - nm_ip4_address_set_prefix (addr, prefix); - nm_ip4_address_set_gateway (addr, gw); - nm_setting_ip4_config_add_address (s_ip4, addr); - nm_ip4_address_unref (addr); + addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, addr); + nm_ip_address_unref (addr); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, @@ -13518,13 +12440,12 @@ test_write_infiniband (void) "infiniband-write", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, NULL, TYPE_INFINIBAND, - NULL, &unmanaged, &keyfile, &routefile, @@ -13565,10 +12486,7 @@ test_read_bond_slave_ib (void) gboolean ignore_error = FALSE; GError *error = NULL; - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring IP4 config on slave*"); connection = connection_from_file (TEST_IFCFG_BOND_SLAVE_IB, - NULL, NULL, NULL, &unmanaged, @@ -13612,11 +12530,7 @@ test_write_bond_slave_ib (void) NMConnection *reread; NMSettingConnection *s_con; NMSettingInfiniband *s_infiniband; - static unsigned char tmpmac[] = { - 0x80, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, - 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22 - }; - GByteArray *mac; + static const char *mac = "80:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22"; char *uuid; gboolean success; GError *error = NULL; @@ -13627,7 +12541,7 @@ test_write_bond_slave_ib (void) char *route6file = NULL; gboolean ignore_error = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -13648,15 +12562,11 @@ test_write_bond_slave_ib (void) s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new (); nm_connection_add_setting (connection, NM_SETTING (s_infiniband)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); - g_object_set (s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NM_SETTING_INFINIBAND_MTU, 2044, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); - g_byte_array_free (mac, TRUE); ASSERT (nm_connection_verify (connection, &error) == TRUE, "bond-slave-write-ib", "failed to verify connection: %s", @@ -13675,11 +12585,10 @@ test_write_bond_slave_ib (void) "bond-slave-write-ib", "didn't get ifcfg file path back after writing connection"); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ reread = connection_from_file (testfile, - NULL, NULL, NULL, &unmanaged, @@ -13731,7 +12640,7 @@ test_read_dcb_basic (void) gboolean expected_pfcs[8] = { TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -13787,8 +12696,8 @@ test_write_dcb_basic (void) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingDcb *s_dcb; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; gboolean success, ignore_error; guint i; char *uuid, *testfile; @@ -13799,7 +12708,7 @@ test_write_dcb_basic (void) const guint traffic_classes[8] = { 3, 4, 7, 2, 1, 0, 5, 6 }; const gboolean pfcs[8] = { TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, NM_SETTING (s_con)); @@ -13817,12 +12726,12 @@ test_write_dcb_basic (void) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP stuff */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + 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_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); /* DCB */ @@ -13864,7 +12773,7 @@ test_write_dcb_basic (void) reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, &error, &ignore_error); @@ -13889,7 +12798,7 @@ test_read_dcb_default_app_priorities (void) gboolean success; connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-default-app-priorities", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); success = nm_connection_verify (connection, &error); @@ -13920,10 +12829,10 @@ test_read_dcb_bad_booleans (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_STRICT value*not all 0s and 1s*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid boolean digit")); g_assert (connection == NULL); } @@ -13937,10 +12846,10 @@ test_read_dcb_short_booleans (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_STRICT value*8 characters*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "boolean array must be 8 characters")); g_assert (connection == NULL); } @@ -13954,10 +12863,10 @@ test_read_dcb_bad_uints (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_UP2TC value*not 0 - 7*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid uint digit")); g_assert (connection == NULL); } @@ -13971,10 +12880,10 @@ test_read_dcb_short_uints (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_UP2TC value*8 characters*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "uint array must be 8 characters")); g_assert (connection == NULL); } @@ -13988,10 +12897,10 @@ test_read_dcb_bad_percent (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_PCT percentage value*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid percent element")); g_assert (connection == NULL); } @@ -14005,10 +12914,10 @@ test_read_dcb_short_percent (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*invalid DCB_PG_PCT percentage list value*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "percent array must be 8 elements")); g_assert (connection == NULL); } @@ -14022,10 +12931,10 @@ test_read_dcb_pgpct_not_100 (void) g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*DCB_PG_PCT percentages do not equal 100*"); connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_test_assert_expected_messages (); - g_assert_error (error, IFCFG_PLUGIN_ERROR, 0); + g_assert_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION); g_assert (strstr (error->message, "invalid percentage sum")); g_assert (connection == NULL); } @@ -14041,7 +12950,7 @@ test_read_fcoe_mode (gconstpointer user_data) char *file; file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-fcoe-%s", expected_mode); - connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_free (file); g_assert_no_error (error); g_assert (connection); @@ -14067,12 +12976,12 @@ test_write_fcoe_mode (gconstpointer user_data) NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingDcb *s_dcb; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; gboolean success, ignore_error; char *uuid, *testfile; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, NM_SETTING (s_con)); @@ -14090,12 +12999,12 @@ test_write_fcoe_mode (gconstpointer user_data) nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP stuff */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + 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_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); /* DCB */ @@ -14134,7 +13043,7 @@ test_write_fcoe_mode (gconstpointer user_data) reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, &error, &ignore_error); @@ -14161,7 +13070,7 @@ test_read_team_master (void) const char *expected_config = "{ \"device\": \"team0\", \"link_watch\": { \"name\": \"ethtool\" } }"; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -14169,13 +13078,14 @@ test_read_team_master (void) g_assert_no_error (error); g_assert (success); + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "team0"); + s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_TEAM_SETTING_NAME); s_team = nm_connection_get_setting_team (connection); g_assert (s_team); - g_assert_cmpstr (nm_setting_team_get_interface_name (s_team), ==, "team0"); g_assert_cmpstr (nm_setting_team_get_config (s_team), ==, expected_config); g_object_unref (connection); @@ -14188,6 +13098,8 @@ test_write_team_master (void) NMSettingConnection *s_con; NMSettingTeam *s_team; NMSettingWired *s_wired; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid, *testfile = NULL, *val; gboolean success; GError *error = NULL; @@ -14195,7 +13107,7 @@ test_write_team_master (void) const char *escaped_expected_config = "\"{ \\\"device\\\": \\\"team0\\\", \\\"link_watch\\\": { \\\"name\\\": \\\"ethtool\\\" } }\""; shvarFile *f; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -14205,6 +13117,7 @@ test_write_team_master (void) g_object_set (s_con, NM_SETTING_CONNECTION_ID, "Test Write Team Master", NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_INTERFACE_NAME, "team0", NM_SETTING_CONNECTION_TYPE, NM_SETTING_TEAM_SETTING_NAME, NULL); g_free (uuid); @@ -14214,7 +13127,6 @@ test_write_team_master (void) nm_connection_add_setting (connection, NM_SETTING (s_team)); g_object_set (s_team, - NM_SETTING_TEAM_INTERFACE_NAME, "team0", NM_SETTING_TEAM_CONFIG, expected_config, NULL); @@ -14222,9 +13134,25 @@ test_write_team_master (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - success = nm_connection_verify (connection, &error); - g_assert_no_error (error); - g_assert (success); + /* IP4 setting */ + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_assert (s_ip4); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_assert (s_ip6); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NULL); + + nmtst_assert_connection_verifies_without_normalization (connection); /* Save the ifcfg */ success = writer_new_connection (connection, @@ -14250,10 +13178,10 @@ test_write_team_master (void) svCloseFile (f); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, + reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); unlink (testfile); g_assert_no_error (error); @@ -14281,7 +13209,7 @@ test_read_team_port (void) const char *expected_config = "{ \"p4p1\": { \"prio\": -10, \"sticky\": true } }"; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -14315,7 +13243,7 @@ test_write_team_port (void) const char *escaped_expected_config = "\"{ \\\"p4p1\\\": { \\\"prio\\\": -10, \\\"sticky\\\": true } }\""; shvarFile *f; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -14373,10 +13301,10 @@ test_write_team_port (void) svCloseFile (f); /* reread will be normalized, so we must normalize connection too. */ - nm_utils_normalize_connection (connection, TRUE); + nm_connection_normalize (connection, NULL, NULL, NULL); /* re-read the connection for comparison */ - reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, + reread = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); unlink (testfile); g_assert_no_error (error); @@ -14402,7 +13330,7 @@ test_read_team_port_empty_config (void) GError *error = NULL; connection = connection_from_file (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-empty-config", - NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL); + NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, &error, NULL); g_assert_no_error (error); g_assert (connection); @@ -14415,8 +13343,11 @@ test_read_team_port_empty_config (void) g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_WIRED_SETTING_NAME); g_assert_cmpstr (nm_setting_connection_get_master (s_con), ==, "team0"); - /* Empty TEAM_PORT_CONFIG means no team-port setting */ - g_assert (nm_connection_get_setting_team_port (connection) == NULL); + /* Normalization adds a team-port setting */ + g_assert (nm_connection_get_setting_team_port (connection)); + + /* empty/missing config */ + g_assert (!nm_setting_team_port_get_config (nm_connection_get_setting_team_port (connection))); g_object_unref (connection); } @@ -14468,13 +13399,13 @@ test_svUnescape_assert (const char *str) } static void -test_svUnescape () +test_svUnescape (void) { int len, repeat, i, k; - GRand *rand = g_rand_new (); + GRand *r = g_rand_new (); guint32 seed = g_random_int (); - g_rand_set_seed (rand, seed); + g_rand_set_seed (r, seed); test_svUnescape_assert (""); test_svUnescape_assert ("'"); @@ -14495,16 +13426,16 @@ test_svUnescape () /* fill the entire string with random. */ for (i = 0; i < len; i++) - s[i] = g_rand_int (rand); + s[i] = g_rand_int (r); /* randomly place escape characters into the string */ - k = g_rand_int (rand) % (len); + k = g_rand_int (r) % (len); while (k-- > 0) - s[g_rand_int (rand) % len] = '\\'; + s[g_rand_int (r) % len] = '\\'; if (len > 1) { /* quote the string. */ - k = g_rand_int (rand) % (10); + k = g_rand_int (r) % (10); if (k < 4) { char quote = k < 2 ? '"' : '\''; @@ -14520,7 +13451,44 @@ test_svUnescape () g_free (s); } - g_rand_free (rand); + g_rand_free (r); +} + +static void +test_read_vlan_trailing_spaces (void) +{ + const char *testfile = TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-trailing-spaces"; + NMConnection *connection; + gboolean success; + GError *error = NULL; + NMSettingVlan *s_vlan; + char *contents = NULL; + + /* Ensure there is whitespace at the end of the VLAN interface name, + * to prevent the whitespace getting stripped off and committed mistakenly + * by something in the future. + */ + success = g_file_get_contents (testfile, &contents, NULL, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (contents && contents[0]); + g_assert (strstr (contents, "DEVICE=\"vlan201\" \n")); + g_free (contents); + + connection = connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL, + NULL, NULL, NULL, &error, NULL); + g_assert_no_error (error); + g_assert (connection != NULL); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "vlan201"); + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "enccw0.0.fb00"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 201); + g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, 0); + + g_object_unref (connection); } @@ -14548,11 +13516,13 @@ int main (int argc, char **argv) nmtst_init_assert_logging (&argc, &argv); g_test_add_func (TPATH "svUnescape", test_svUnescape); + g_test_add_func (TPATH "vlan-trailing-spaces", test_read_vlan_trailing_spaces); g_test_add_func (TPATH "unmanaged", test_read_unmanaged); g_test_add_func (TPATH "unmanaged-unrecognized", test_read_unmanaged_unrecognized); g_test_add_func (TPATH "unrecognized", test_read_unrecognized); g_test_add_func (TPATH "basic", test_read_basic); + g_test_add_func (TPATH "miscellaneous-variables", test_read_miscellaneous_variables); g_test_add_func (TPATH "variables-corner-cases", test_read_variables_corner_cases); g_test_add_data_func (TPATH "no-prefix/8", GUINT_TO_POINTER (8), test_read_wired_static_no_prefix); g_test_add_data_func (TPATH "no-prefix/16", GUINT_TO_POINTER (16), test_read_wired_static_no_prefix); @@ -14560,18 +13530,18 @@ int main (int argc, char **argv) g_test_add_data_func (TPATH "static-ip6-only-gw/_NULL_", NULL, test_write_wired_static_ip6_only_gw); g_test_add_data_func (TPATH "static-ip6-only-gw/::", "::", test_write_wired_static_ip6_only_gw); g_test_add_data_func (TPATH "static-ip6-only-gw/2001:db8:8:4::2", "2001:db8:8:4::2", test_write_wired_static_ip6_only_gw); - g_test_add_data_func (TPATH "static-ip6-only-gw/ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255", "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255", test_write_wired_static_ip6_only_gw); + g_test_add_data_func (TPATH "static-ip6-only-gw/::ffff:255.255.255.255", "::ffff:255.255.255.255", test_write_wired_static_ip6_only_gw); test_read_wired_static (TEST_IFCFG_WIRED_STATIC, "System test-wired-static", TRUE); test_read_wired_static (TEST_IFCFG_WIRED_STATIC_BOOTPROTO, "System test-wired-static-bootproto", FALSE); test_read_wired_dhcp (); g_test_add_func (TPATH "dhcp-plus-ip", test_read_wired_dhcp_plus_ip); g_test_add_func (TPATH "dhcp-send-hostname", test_read_write_wired_dhcp_send_hostname); - test_read_wired_global_gateway (); - test_read_wired_never_default (); + g_test_add_func (TPATH "global-gateway", test_read_wired_global_gateway); + g_test_add_func (TPATH "never-default", test_read_wired_never_default); test_read_wired_defroute_no (); test_read_wired_defroute_no_gatewaydev_yes (); - test_read_wired_static_routes (); + g_test_add_func (TPATH "routes/read-static", test_read_wired_static_routes); test_read_wired_static_routes_legacy (); test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_1, "System test-wired-ipv4-manual-1"); test_read_wired_ipv4_manual (TEST_IFCFG_WIRED_IPV4_MANUAL_2, "System test-wired-ipv4-manual-2"); @@ -14617,6 +13587,9 @@ int main (int argc, char **argv) test_read_wifi_wpa_eap_tls (); test_read_wifi_wpa_eap_ttls_tls (); test_read_wifi_wep_eap_ttls_chap (); + g_test_add_func (TPATH "wifi/read-band-a", test_read_wifi_band_a); + g_test_add_func (TPATH "wifi/read-band-a-channel-mismatch", test_read_wifi_band_a_channel_mismatch); + g_test_add_func (TPATH "wifi/read-band-bg-channel-mismatch", test_read_wifi_band_bg_channel_mismatch); g_test_add_func (TPATH "wifi/read-hidden", test_read_wifi_hidden); test_read_wired_qeth_static (); test_read_wired_ctc_static (); @@ -14697,6 +13670,7 @@ int main (int argc, char **argv) test_write_wifi_wpa_then_open (); test_write_wifi_wpa_then_wep_with_perms (); g_test_add_func (TPATH "wifi/write-hidden", test_write_wifi_hidden); + g_test_add_func (TPATH "wifi/write-band-a", test_write_wifi_band_a); test_write_wired_qeth_dhcp (); test_write_wired_ctc_dhcp (); test_write_permissions (); @@ -14707,14 +13681,9 @@ int main (int argc, char **argv) test_write_ethernet_missing_ipv6 (); /* iSCSI / ibft */ - test_read_ibft_dhcp (); - test_read_ibft_static (); - test_read_ibft_malformed ("ibft-bad-record-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-record", FALSE); - test_read_ibft_malformed ("ibft-bad-entry-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-entry", TRUE); - test_read_ibft_malformed ("ibft-bad-ipaddr-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-ipaddr", TRUE); - test_read_ibft_malformed ("ibft-bad-gateway-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-gateway", TRUE); - test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1", TRUE); - test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2", TRUE); + g_test_add_func (TPATH "ibft/ignored", test_read_ibft_ignored); + + /* Data Center Bridging (DCB) */ g_test_add_func (TPATH "dcb/read-basic", test_read_dcb_basic); g_test_add_func (TPATH "dcb/write-basic", test_write_dcb_basic); g_test_add_func (TPATH "dcb/default-app-priorities", test_read_dcb_default_app_priorities); diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c index 8318a65d..5b9e9d79 100644 --- a/src/settings/plugins/ifcfg-rh/utils.c +++ b/src/settings/plugins/ifcfg-rh/utils.c @@ -18,9 +18,14 @@ * (C) Copyright 2008 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include + +#include "nm-core-internal.h" + #include "utils.h" #include "shvar.h" @@ -37,7 +42,7 @@ char * utils_single_quote_string (const char *str) { - static const char const drop_chars[] = "\r\n"; /* drop CR and LF */ + static const char *drop_chars = "\r\n"; /* drop CR and LF */ static const char escape_char = '\\'; /* escape char is backslash */ static const char quote_char = '\''; /* quote char is single quote */ size_t i, slen, j = 0; diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 60af599b..f4ffffd6 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -15,9 +15,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2013 Red Hat, Inc. + * Copyright 2009 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -27,7 +29,6 @@ #include #include #include -#include #include #include @@ -39,7 +40,7 @@ #include #include #include -#include +#include "nm-core-internal.h" #include #include "nm-logging.h" @@ -51,13 +52,6 @@ #include "crypto.h" -static void -svSetValue_free (shvarFile *s, const char *key, char *value, gboolean verbatim) -{ - svSetValue (s, key, value, verbatim); - g_free (value); -} - static void save_secret_flags (shvarFile *ifcfg, const char *key, @@ -156,7 +150,7 @@ write_secret_file (const char *path, errno = 0; fd = mkstemp (tmppath); if (fd < 0) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not create temporary file for '%s': %d", path, errno); goto out; @@ -167,7 +161,7 @@ write_secret_file (const char *path, if (fchmod (fd, S_IRUSR | S_IWUSR)) { close (fd); unlink (tmppath); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not set permissions for temporary file '%s': %d", path, errno); goto out; @@ -178,7 +172,7 @@ write_secret_file (const char *path, if (written != len) { close (fd); unlink (tmppath); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not write temporary file for '%s': %d", path, errno); goto out; @@ -189,7 +183,7 @@ write_secret_file (const char *path, errno = 0; if (rename (tmppath, path)) { unlink (tmppath); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not rename temporary file to '%s': %d", path, errno); goto out; @@ -205,7 +199,7 @@ typedef struct ObjectType { const char *setting_key; NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting); const char * (*path_func) (NMSetting8021x *setting); - const GByteArray * (*blob_func) (NMSetting8021x *setting); + GBytes * (*blob_func) (NMSetting8021x *setting); const char *ifcfg_key; const char *suffix; } ObjectType; @@ -290,7 +284,7 @@ write_object (NMSetting8021x *s_8021x, { NMSetting8021xCKScheme scheme; const char *path = NULL; - const GByteArray *blob = NULL; + GBytes *blob = NULL; g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (objtype != NULL, FALSE); @@ -345,7 +339,7 @@ write_object (NMSetting8021x *s_8021x, new_file = utils_cert_path (ifcfg->fileName, objtype->suffix); if (!new_file) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not create file path for %s / %s", NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key); return FALSE; @@ -355,13 +349,16 @@ write_object (NMSetting8021x *s_8021x, * can use paths from now on instead of pushing around the certificate * data itself. */ - success = write_secret_file (new_file, (const char *) blob->data, blob->len, &write_error); + success = write_secret_file (new_file, + (const char *) g_bytes_get_data (blob, NULL), + g_bytes_get_size (blob), + &write_error); if (success) { svSetValue (ifcfg, objtype->ifcfg_key, new_file, FALSE); g_free (new_file); return TRUE; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not write certificate/key for %s / %s: %s", NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key, (write_error && write_error->message) ? write_error->message : "(unknown)"); @@ -614,7 +611,7 @@ write_wireless_security_setting (NMConnection *connection, s_wsec = nm_connection_get_setting_wireless_security (connection); if (!s_wsec) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; } @@ -808,49 +805,37 @@ write_wireless_setting (NMConnection *connection, { NMSettingWireless *s_wireless; char *tmp, *tmp2; - const GByteArray *ssid, *device_mac, *cloned_mac, *bssid; - const char *mode; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; + const char *mode, *bssid; + const char *device_mac, *cloned_mac; char buf[33]; guint32 mtu, chan, i; gboolean adhoc = FALSE, hex_ssid = FALSE; - const GSList *macaddr_blacklist; + const char * const *macaddr_blacklist; s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; } - svSetValue (ifcfg, "HWADDR", NULL, FALSE); device_mac = nm_setting_wireless_get_mac_address (s_wireless); - if (device_mac) { - svSetValue_free (ifcfg, "HWADDR", - nm_utils_hwaddr_ntoa_len (device_mac->data, device_mac->len), FALSE); - } + svSetValue (ifcfg, "HWADDR", device_mac, FALSE); - svSetValue (ifcfg, "MACADDR", NULL, FALSE); cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless); - if (cloned_mac) { - svSetValue_free (ifcfg, "MACADDR", - nm_utils_hwaddr_ntoa_len (cloned_mac->data, cloned_mac->len), FALSE); - } + svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE); macaddr_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); - if (macaddr_blacklist) { - const GSList *iter; - GString *blacklist_str = g_string_new (NULL); + if (macaddr_blacklist[0]) { + char *blacklist_str; - for (iter = macaddr_blacklist; iter; iter = g_slist_next (iter)) { - g_string_append (blacklist_str, iter->data); - g_string_append_c (blacklist_str, ' '); - - } - if (blacklist_str->len > 0) - g_string_truncate (blacklist_str, blacklist_str->len - 1); - svSetValue (ifcfg, "HWADDR_BLACKLIST", blacklist_str->str, FALSE); - g_string_free (blacklist_str, TRUE); + blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); + svSetValue (ifcfg, "HWADDR_BLACKLIST", blacklist_str, FALSE); + g_free (blacklist_str); } svSetValue (ifcfg, "MTU", NULL, FALSE); @@ -863,12 +848,13 @@ write_wireless_setting (NMConnection *connection, ssid = nm_setting_wireless_get_ssid (s_wireless); if (!ssid) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; } - if (!ssid->len || ssid->len > 32) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + ssid_data = g_bytes_get_data (ssid, &ssid_len); + if (!ssid_len || ssid_len > 32) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Invalid SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; } @@ -876,8 +862,8 @@ write_wireless_setting (NMConnection *connection, /* If the SSID contains any non-printable characters, we need to use the * hex notation of the SSID instead. */ - for (i = 0; i < ssid->len; i++) { - if (!g_ascii_isprint (ssid->data[i])) { + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isprint (ssid_data[i])) { hex_ssid = TRUE; break; } @@ -887,16 +873,16 @@ write_wireless_setting (NMConnection *connection, GString *str; /* Hex SSIDs don't get quoted */ - str = g_string_sized_new (ssid->len * 2 + 3); + str = g_string_sized_new (ssid_len * 2 + 3); g_string_append (str, "0x"); - for (i = 0; i < ssid->len; i++) - g_string_append_printf (str, "%02X", ssid->data[i]); + for (i = 0; i < ssid_len; i++) + g_string_append_printf (str, "%02X", ssid_data[i]); svSetValue (ifcfg, "ESSID", str->str, TRUE); g_string_free (str, TRUE); } else { /* Printable SSIDs always get quoted */ memset (buf, 0, sizeof (buf)); - memcpy (buf, ssid->data, ssid->len); + memcpy (buf, ssid_data, ssid_len); tmp = svEscape (buf); /* svEscape will usually quote the string, but just for consistency, @@ -917,27 +903,29 @@ write_wireless_setting (NMConnection *connection, } else if (!strcmp (mode, "adhoc")) { svSetValue (ifcfg, "MODE", "Ad-Hoc", FALSE); adhoc = TRUE; + } else if (!strcmp (mode, "ap")) { + svSetValue (ifcfg, "MODE", "Ap", FALSE); } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Invalid mode '%s' in '%s' setting", mode, NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; } svSetValue (ifcfg, "CHANNEL", NULL, FALSE); + svSetValue (ifcfg, "BAND", NULL, FALSE); chan = nm_setting_wireless_get_channel (s_wireless); if (chan) { tmp = g_strdup_printf ("%u", chan); svSetValue (ifcfg, "CHANNEL", tmp, FALSE); g_free (tmp); + } else { + /* Band only set if channel is not, since channel implies band */ + svSetValue (ifcfg, "BAND", nm_setting_wireless_get_band (s_wireless), FALSE); } - svSetValue (ifcfg, "BSSID", NULL, FALSE); bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid) { - svSetValue_free (ifcfg, "BSSID", - nm_utils_hwaddr_ntoa_len (bssid->data, bssid->len), FALSE); - } + svSetValue (ifcfg, "BSSID", bssid, FALSE); /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security; * otherwise there's no way to detect WEP vs. open when WEP keys aren't @@ -994,26 +982,20 @@ static gboolean write_infiniband_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingInfiniband *s_infiniband; - const GByteArray *mac; char *tmp; - const char *transport_mode, *parent; + const char *mac, *transport_mode, *parent; guint32 mtu; int p_key; s_infiniband = nm_connection_get_setting_infiniband (connection); if (!s_infiniband) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_INFINIBAND_SETTING_NAME); return FALSE; } - svSetValue (ifcfg, "HWADDR", NULL, FALSE); mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac) { - tmp = nm_utils_hwaddr_ntoa (mac->data, ARPHRD_INFINIBAND); - svSetValue (ifcfg, "HWADDR", tmp, FALSE); - g_free (tmp); - } + svSetValue (ifcfg, "HWADDR", mac, FALSE); svSetValue (ifcfg, "MTU", NULL, FALSE); mtu = nm_setting_infiniband_get_mtu (s_infiniband); @@ -1049,50 +1031,35 @@ static gboolean write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; - const GByteArray *device_mac, *cloned_mac; + const char *device_mac, *cloned_mac; char *tmp; const char *nettype, *portname, *ctcprot, *s390_key, *s390_val; guint32 mtu, num_opts, i; - const GPtrArray *s390_subchannels; + const char *const *s390_subchannels; GString *str; - const GSList *macaddr_blacklist; + const char * const *macaddr_blacklist; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME); return FALSE; } - svSetValue (ifcfg, "HWADDR", NULL, FALSE); device_mac = nm_setting_wired_get_mac_address (s_wired); - if (device_mac) { - svSetValue_free (ifcfg, "HWADDR", - nm_utils_hwaddr_ntoa_len (device_mac->data, device_mac->len), FALSE); - } + svSetValue (ifcfg, "HWADDR", device_mac, FALSE); - svSetValue (ifcfg, "MACADDR", NULL, FALSE); cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac) { - svSetValue_free (ifcfg, "MACADDR", - nm_utils_hwaddr_ntoa_len (cloned_mac->data, cloned_mac->len), FALSE); - } + svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); svSetValue (ifcfg, "HWADDR_BLACKLIST", NULL, FALSE); macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); - if (macaddr_blacklist) { - const GSList *iter; - GString *blacklist_str = g_string_new (NULL); - - for (iter = macaddr_blacklist; iter; iter = g_slist_next (iter)) { - g_string_append (blacklist_str, iter->data); - g_string_append_c (blacklist_str, ' '); + if (macaddr_blacklist[0]) { + char *blacklist_str; - } - if (blacklist_str->len > 0) - g_string_truncate (blacklist_str, blacklist_str->len - 1); - svSetValue (ifcfg, "HWADDR_BLACKLIST", blacklist_str->str, FALSE); - g_string_free (blacklist_str, TRUE); + blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); + svSetValue (ifcfg, "HWADDR_BLACKLIST", blacklist_str, FALSE); + g_free (blacklist_str); } svSetValue (ifcfg, "MTU", NULL, FALSE); @@ -1106,16 +1073,14 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "SUBCHANNELS", NULL, FALSE); s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); if (s390_subchannels) { + int len = g_strv_length ((char **)s390_subchannels); + tmp = NULL; - if (s390_subchannels->len == 2) { - tmp = g_strdup_printf ("%s,%s", - (const char *) g_ptr_array_index (s390_subchannels, 0), - (const char *) g_ptr_array_index (s390_subchannels, 1)); - } else if (s390_subchannels->len == 3) { - tmp = g_strdup_printf ("%s,%s,%s", - (const char *) g_ptr_array_index (s390_subchannels, 0), - (const char *) g_ptr_array_index (s390_subchannels, 1), - (const char *) g_ptr_array_index (s390_subchannels, 2)); + if (len == 2) { + tmp = g_strdup_printf ("%s,%s", s390_subchannels[0], s390_subchannels[1]); + } else if (len == 3) { + tmp = g_strdup_printf ("%s,%s,%s", s390_subchannels[0], s390_subchannels[1], + s390_subchannels[2]); } svSetValue (ifcfg, "SUBCHANNELS", tmp, FALSE); g_free (tmp); @@ -1161,11 +1126,11 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } -static GString * +static char * vlan_priority_maplist_to_stringlist (NMSettingVlan *s_vlan, NMVlanPriorityMap map) { - GSList *strlist = NULL, *iter; - GString *value = NULL; + char **strlist; + char *value; if (map == NM_VLAN_INGRESS_MAP) g_object_get (G_OBJECT (s_vlan), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP, &strlist, NULL); @@ -1174,11 +1139,11 @@ vlan_priority_maplist_to_stringlist (NMSettingVlan *s_vlan, NMVlanPriorityMap ma else return NULL; - value = g_string_new (""); - for (iter = strlist; iter; iter = g_slist_next (iter)) - g_string_append_printf (value, "%s%s", value->len ? "," : "", (const char *) iter->data); - - g_slist_free_full (strlist, g_free); + if (strlist[0]) + value = g_strjoinv (",", strlist); + else + value = NULL; + g_strfreev (strlist); return value; } @@ -1191,25 +1156,25 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, NMSettingWired *s_wired; char *tmp; guint32 vlan_flags = 0; - GString *text = NULL; s_con = nm_connection_get_setting_connection (connection); if (!s_con) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing connection setting"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Missing connection setting"); return FALSE; } s_vlan = nm_connection_get_setting_vlan (connection); if (!s_vlan) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "Missing VLAN setting"); + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Missing VLAN setting"); return FALSE; } svSetValue (ifcfg, "VLAN", "yes", FALSE); svSetValue (ifcfg, "TYPE", TYPE_VLAN, FALSE); - svSetValue (ifcfg, "DEVICE", nm_setting_vlan_get_interface_name (s_vlan), FALSE); + svSetValue (ifcfg, "DEVICE", nm_setting_connection_get_interface_name (s_con), FALSE); svSetValue (ifcfg, "PHYSDEV", nm_setting_vlan_get_parent (s_vlan), FALSE); - svSetValue (ifcfg, "MASTER", nm_setting_connection_get_master (s_con), FALSE); tmp = g_strdup_printf ("%d", nm_setting_vlan_get_id (s_vlan)); svSetValue (ifcfg, "VLAN_ID", tmp, FALSE); @@ -1230,15 +1195,13 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, } else if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) svSetValue (ifcfg, "VLAN_FLAGS", "LOOSE_BINDING", FALSE); - text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP); - svSetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE); - if (text) - g_string_free (text, TRUE); + tmp = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP); + svSetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", tmp, FALSE); + g_free (tmp); - text = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_EGRESS_MAP); - svSetValue (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", text ? text->str : NULL, FALSE); - if (text) - g_string_free (text, TRUE); + tmp = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_EGRESS_MAP); + svSetValue (ifcfg, "VLAN_EGRESS_PRIORITY_MAP", tmp, FALSE); + g_free (tmp); svSetValue (ifcfg, "HWADDR", NULL, FALSE); svSetValue (ifcfg, "MACADDR", NULL, FALSE); @@ -1246,24 +1209,18 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, s_wired = nm_connection_get_setting_wired (connection); if (s_wired) { - const GByteArray *device_mac, *cloned_mac; + const char *device_mac, *cloned_mac; guint32 mtu; *wired = TRUE; device_mac = nm_setting_wired_get_mac_address (s_wired); - if (device_mac) { - tmp = nm_utils_hwaddr_ntoa (device_mac->data, ARPHRD_ETHER); - svSetValue (ifcfg, "HWADDR", tmp, FALSE); - g_free (tmp); - } + if (device_mac) + svSetValue (ifcfg, "HWADDR", device_mac, FALSE); cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); - if (cloned_mac) { - tmp = nm_utils_hwaddr_ntoa (cloned_mac->data, ARPHRD_ETHER); - svSetValue (ifcfg, "MACADDR", tmp, FALSE); - g_free (tmp); - } + if (cloned_mac) + svSetValue (ifcfg, "MACADDR", cloned_mac, FALSE); mtu = nm_setting_wired_get_mtu (s_wired); if (mtu) { @@ -1285,14 +1242,15 @@ write_bonding_setting (NMConnection *connection, shvarFile *ifcfg, GError **erro s_bond = nm_connection_get_setting_bond (connection); if (!s_bond) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_BOND_SETTING_NAME); return FALSE; } - iface = nm_setting_bond_get_interface_name (s_bond); + iface = nm_connection_get_interface_name (connection); if (!iface) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing interface name"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Missing interface name"); return FALSE; } @@ -1336,14 +1294,15 @@ write_team_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) s_team = nm_connection_get_setting_team (connection); if (!s_team) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_TEAM_SETTING_NAME); return FALSE; } - iface = nm_setting_team_get_interface_name (s_team); + iface = nm_connection_get_interface_name (connection); if (!iface) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing interface name"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Missing interface name"); return FALSE; } @@ -1379,19 +1338,20 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, GError **error const char *iface; guint32 i; GString *opts; - const GByteArray *mac; + const char *mac; char *s; s_bridge = nm_connection_get_setting_bridge (connection); if (!s_bridge) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing '%s' setting", NM_SETTING_BRIDGE_SETTING_NAME); return FALSE; } - iface = nm_setting_bridge_get_interface_name (s_bridge); + iface = nm_connection_get_interface_name (connection); if (!iface) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing interface name"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Missing interface name"); return FALSE; } @@ -1399,11 +1359,9 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, GError **error svSetValue (ifcfg, "BRIDGING_OPTS", NULL, FALSE); svSetValue (ifcfg, "STP", "no", FALSE); svSetValue (ifcfg, "DELAY", NULL, FALSE); - svSetValue (ifcfg, "MACADDR", NULL, FALSE); mac = nm_setting_bridge_get_mac_address (s_bridge); - if (mac) - svSetValue_free (ifcfg, "MACADDR", nm_utils_hwaddr_ntoa_len (mac->data, mac->len), FALSE); + svSetValue (ifcfg, "MACADDR", mac, FALSE); /* Bridge options */ opts = g_string_sized_new (32); @@ -1701,6 +1659,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) GString *str; const char *master; char *tmp; + gint i_int; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); @@ -1709,6 +1668,12 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no", FALSE); + i_int = nm_setting_connection_get_autoconnect_priority (s_con); + tmp = i_int != NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT + ? g_strdup_printf ("%d", i_int) : NULL; + svSetValue (ifcfg, "AUTOCONNECT_PRIORITY", tmp, FALSE); + g_free (tmp); + /* Permissions */ svSetValue (ifcfg, "USERS", NULL, FALSE); n = nm_setting_connection_get_num_permissions (s_con); @@ -1778,14 +1743,14 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) } static gboolean -write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error) +write_route_file_legacy (const char *filename, NMSettingIPConfig *s_ip4, GError **error) { - char dest[INET_ADDRSTRLEN]; - char next_hop[INET_ADDRSTRLEN]; + const char *dest, *next_hop; char **route_items; char *route_contents; - NMIP4Route *route; - guint32 ip, prefix, metric; + NMIPRoute *route; + guint32 prefix; + gint64 metric; guint32 i, num; gboolean success = FALSE; @@ -1794,7 +1759,7 @@ write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError g_return_val_if_fail (error != NULL, FALSE); g_return_val_if_fail (*error == NULL, FALSE); - num = nm_setting_ip4_config_get_num_routes (s_ip4); + num = nm_setting_ip_config_get_num_routes (s_ip4); if (num == 0) { unlink (filename); return TRUE; @@ -1802,28 +1767,24 @@ write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError route_items = g_malloc0 (sizeof (char*) * (num + 1)); for (i = 0; i < num; i++) { - route = nm_setting_ip4_config_get_route (s_ip4, i); - - memset (dest, 0, sizeof (dest)); - ip = nm_ip4_route_get_dest (route); - inet_ntop (AF_INET, (const void *) &ip, &dest[0], sizeof (dest)); - - prefix = nm_ip4_route_get_prefix (route); + route = nm_setting_ip_config_get_route (s_ip4, i); - memset (next_hop, 0, sizeof (next_hop)); - ip = nm_ip4_route_get_next_hop (route); - inet_ntop (AF_INET, (const void *) &ip, &next_hop[0], sizeof (next_hop)); + dest = nm_ip_route_get_dest (route); + prefix = nm_ip_route_get_prefix (route); + next_hop = nm_ip_route_get_next_hop (route); + metric = nm_ip_route_get_metric (route); - metric = nm_ip4_route_get_metric (route); - - route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric); + if (metric == -1) + route_items[i] = g_strdup_printf ("%s/%u via %s\n", dest, prefix, next_hop); + else + route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, (guint32) metric); } route_items[num] = NULL; route_contents = g_strjoinv (NULL, route_items); g_strfreev (route_items); if (!g_file_set_contents (filename, route_contents, -1, NULL)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Writing route file '%s' failed", filename); goto error; } @@ -1839,7 +1800,7 @@ error: static gboolean write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; const char *value; char *addr_key, *prefix_key, *netmask_key, *gw_key, *metric_key, *tmp; char *route_path = NULL; @@ -1852,7 +1813,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) - method = nm_setting_ip4_config_get_method (s_ip4); + method = nm_setting_ip_config_get_method (s_ip4); /* Missing IP4 setting is assumed to be DHCP */ if (!method) @@ -1895,7 +1856,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) /* Temporarily create fake IP4 setting if missing; method set to DHCP above */ if (!s_ip4) { - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); fake_ip4 = TRUE; } @@ -1922,14 +1883,19 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) /* Write out IPADDR, PREFIX, GATEWAY for current IP addresses * without labels. Unset obsolete NETMASK. */ - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); for (i = n = 0; i < num; i++) { - char buf[INET_ADDRSTRLEN]; - NMIP4Address *addr; - guint32 ip; + NMIPAddress *addr; - if (i > 0 && NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i))) - continue; + addr = nm_setting_ip_config_get_address (s_ip4, i); + + if (i > 0) { + GVariant *label; + + label = nm_ip_address_get_attribute (addr, "label"); + if (label) + continue; + } if (n == 0) { /* Instead of index 0 use un-numbered variables. @@ -1948,26 +1914,14 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) gw_key = g_strdup_printf ("GATEWAY%d", n); } - addr = nm_setting_ip4_config_get_address (s_ip4, i); - - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_address (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (ifcfg, addr_key, &buf[0], FALSE); + svSetValue (ifcfg, addr_key, nm_ip_address_get_address (addr), FALSE); - tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr)); + tmp = g_strdup_printf ("%u", nm_ip_address_get_prefix (addr)); svSetValue (ifcfg, prefix_key, tmp, FALSE); g_free (tmp); svSetValue (ifcfg, netmask_key, NULL, FALSE); - - if (nm_ip4_address_get_gateway (addr)) { - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_gateway (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (ifcfg, gw_key, &buf[0], FALSE); - } else - svSetValue (ifcfg, gw_key, NULL, FALSE); + svSetValue (ifcfg, gw_key, NULL, FALSE); g_free (addr_key); g_free (prefix_key); @@ -1994,32 +1948,30 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) g_free (gw_key); } - num = nm_setting_ip4_config_get_num_dns (s_ip4); + svSetValue (ifcfg, "GATEWAY", nm_setting_ip_config_get_gateway (s_ip4), FALSE); + + num = nm_setting_ip_config_get_num_dns (s_ip4); for (i = 0; i < 254; i++) { - char buf[INET_ADDRSTRLEN + 1]; - guint32 ip; + const char *dns; addr_key = g_strdup_printf ("DNS%d", i + 1); if (i >= num) svSetValue (ifcfg, addr_key, NULL, FALSE); else { - ip = nm_setting_ip4_config_get_dns (s_ip4, i); - - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (ifcfg, addr_key, &buf[0], FALSE); + dns = nm_setting_ip_config_get_dns (s_ip4, i); + svSetValue (ifcfg, addr_key, dns, FALSE); } g_free (addr_key); } - num = nm_setting_ip4_config_get_num_dns_searches (s_ip4); + num = nm_setting_ip_config_get_num_dns_searches (s_ip4); if (num > 0) { searches = g_string_new (NULL); for (i = 0; i < num; i++) { if (i > 0) g_string_append_c (searches, ' '); - g_string_append (searches, nm_setting_ip4_config_get_dns_search (s_ip4, i)); + g_string_append (searches, nm_setting_ip_config_get_dns_search (s_ip4, i)); } svSetValue (ifcfg, "DOMAIN", searches->str, FALSE); g_string_free (searches, TRUE); @@ -2028,7 +1980,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) /* DEFROUTE; remember that it has the opposite meaning from never-default */ svSetValue (ifcfg, "DEFROUTE", - nm_setting_ip4_config_get_never_default (s_ip4) ? "no" : "yes", + nm_setting_ip_config_get_never_default (s_ip4) ? "no" : "yes", FALSE); svSetValue (ifcfg, "PEERDNS", NULL, FALSE); @@ -2036,14 +1988,14 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "DHCP_CLIENT_ID", NULL, FALSE); if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { svSetValue (ifcfg, "PEERDNS", - nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) ? "no" : "yes", + nm_setting_ip_config_get_ignore_auto_dns (s_ip4) ? "no" : "yes", FALSE); svSetValue (ifcfg, "PEERROUTES", - nm_setting_ip4_config_get_ignore_auto_routes (s_ip4) ? "no" : "yes", + nm_setting_ip_config_get_ignore_auto_routes (s_ip4) ? "no" : "yes", FALSE); - value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); + value = nm_setting_ip_config_get_dhcp_hostname (s_ip4); if (value) svSetValue (ifcfg, "DHCP_HOSTNAME", value, FALSE); @@ -2051,22 +2003,22 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) * in that case, because it is NM-specific variable */ svSetValue (ifcfg, "DHCP_SEND_HOSTNAME", - nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) ? NULL : "no", + nm_setting_ip_config_get_dhcp_send_hostname (s_ip4) ? NULL : "no", FALSE); - value = nm_setting_ip4_config_get_dhcp_client_id (s_ip4); + value = nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)); if (value) svSetValue (ifcfg, "DHCP_CLIENT_ID", value, FALSE); } svSetValue (ifcfg, "IPV4_FAILURE_FATAL", - nm_setting_ip4_config_get_may_fail (s_ip4) ? "no" : "yes", + nm_setting_ip_config_get_may_fail (s_ip4) ? "no" : "yes", FALSE); /* Static routes - route- file */ route_path = utils_get_route_path (ifcfg->fileName); if (!route_path) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not get route file path for '%s'", ifcfg->fileName); goto out; } @@ -2076,18 +2028,19 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) routefile = utils_get_route_ifcfg (ifcfg->fileName, TRUE); if (!routefile) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not create route file '%s'", route_path); g_free (route_path); goto out; } g_free (route_path); - num = nm_setting_ip4_config_get_num_routes (s_ip4); + num = nm_setting_ip_config_get_num_routes (s_ip4); for (i = 0; i < 256; i++) { char buf[INET_ADDRSTRLEN]; - NMIP4Route *route; - guint32 ip, metric; + NMIPRoute *route; + guint32 netmask; + gint64 metric; addr_key = g_strdup_printf ("ADDRESS%d", i); netmask_key = g_strdup_printf ("NETMASK%d", i); @@ -2100,29 +2053,23 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (routefile, gw_key, NULL, FALSE); svSetValue (routefile, metric_key, NULL, FALSE); } else { - route = nm_setting_ip4_config_get_route (s_ip4, i); + route = nm_setting_ip_config_get_route (s_ip4, i); - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_route_get_dest (route); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (routefile, addr_key, &buf[0], FALSE); + svSetValue (routefile, addr_key, nm_ip_route_get_dest (route), FALSE); memset (buf, 0, sizeof (buf)); - ip = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route)); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); + netmask = nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route)); + inet_ntop (AF_INET, (const void *) &netmask, &buf[0], sizeof (buf)); svSetValue (routefile, netmask_key, &buf[0], FALSE); - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_route_get_next_hop (route); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (routefile, gw_key, &buf[0], FALSE); + svSetValue (routefile, gw_key, nm_ip_route_get_next_hop (route), FALSE); memset (buf, 0, sizeof (buf)); - metric = nm_ip4_route_get_metric (route); - if (metric == 0) + metric = nm_ip_route_get_metric (route); + if (metric == -1) svSetValue (routefile, metric_key, NULL, FALSE); else { - tmp = g_strdup_printf ("%u", metric); + tmp = g_strdup_printf ("%u", (guint32) metric); svSetValue (routefile, metric_key, tmp, FALSE); g_free (tmp); } @@ -2157,7 +2104,7 @@ out: static void write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) { - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *base_ifcfg_dir, *base_ifcfg_name, *base_name; int i, num, base_ifcfg_name_len, base_name_len; GDir *dir; @@ -2195,17 +2142,20 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) if (!s_ip4) return; - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); for (i = 0; i < num; i++) { + GVariant *label_var; const char *label, *p; - char buf[INET_ADDRSTRLEN], *path, *tmp; - NMIP4Address *addr; - guint32 ip; + char *path, *tmp; + NMIPAddress *addr; shvarFile *ifcfg; - label = NM_UTILS_PRIVATE_CALL (nm_setting_ip4_config_get_address_label (s_ip4, i)); - if (!label) + addr = nm_setting_ip_config_get_address (s_ip4, i); + + label_var = nm_ip_address_get_attribute (addr, "label"); + if (!label_var) continue; + label = g_variant_get_string (label_var, NULL); if ( strncmp (label, base_name, base_name_len) != 0 || label[base_name_len] != ':') continue; @@ -2223,24 +2173,13 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) svSetValue (ifcfg, "DEVICE", label, FALSE); - addr = nm_setting_ip4_config_get_address (s_ip4, i); - - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_address (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (ifcfg, "IPADDR", &buf[0], FALSE); + addr = nm_setting_ip_config_get_address (s_ip4, i); + svSetValue (ifcfg, "IPADDR", nm_ip_address_get_address (addr), FALSE); - tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr)); + tmp = g_strdup_printf ("%u", nm_ip_address_get_prefix (addr)); svSetValue (ifcfg, "PREFIX", tmp, FALSE); g_free (tmp); - if (nm_ip4_address_get_gateway (addr)) { - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_gateway (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf)); - svSetValue (ifcfg, "GATEWAY", &buf[0], FALSE); - } - svWriteFile (ifcfg, 0644, NULL); svCloseFile (ifcfg); } @@ -2250,15 +2189,11 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path) } static gboolean -write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error) +write_route6_file (const char *filename, NMSettingIPConfig *s_ip6, GError **error) { - char dest[INET6_ADDRSTRLEN]; - char next_hop[INET6_ADDRSTRLEN]; char **route_items; char *route_contents; - NMIP6Route *route; - const struct in6_addr *ip; - guint32 prefix, metric; + NMIPRoute *route; guint32 i, num; gboolean success = FALSE; @@ -2267,7 +2202,7 @@ write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **err g_return_val_if_fail (error != NULL, FALSE); g_return_val_if_fail (*error == NULL, FALSE); - num = nm_setting_ip6_config_get_num_routes (s_ip6); + num = nm_setting_ip_config_get_num_routes (s_ip6); if (num == 0) { unlink (filename); return TRUE; @@ -2275,28 +2210,27 @@ write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **err route_items = g_malloc0 (sizeof (char*) * (num + 1)); for (i = 0; i < num; i++) { - route = nm_setting_ip6_config_get_route (s_ip6, i); - - memset (dest, 0, sizeof (dest)); - ip = nm_ip6_route_get_dest (route); - inet_ntop (AF_INET6, (const void *) ip, &dest[0], sizeof (dest)); - - prefix = nm_ip6_route_get_prefix (route); + route = nm_setting_ip_config_get_route (s_ip6, i); - memset (next_hop, 0, sizeof (next_hop)); - ip = nm_ip6_route_get_next_hop (route); - inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], sizeof (next_hop)); - - metric = nm_ip6_route_get_metric (route); - - route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric); + if (nm_ip_route_get_metric (route) == -1) { + route_items[i] = g_strdup_printf ("%s/%u via %s\n", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + nm_ip_route_get_next_hop (route)); + } else { + route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + nm_ip_route_get_next_hop (route), + (guint32) nm_ip_route_get_metric (route)); + } } route_items[num] = NULL; route_contents = g_strjoinv (NULL, route_items); g_strfreev (route_items); if (!g_file_set_contents (filename, route_contents, -1, NULL)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Writing route6 file '%s' failed", filename); goto error; } @@ -2311,16 +2245,14 @@ error: static gboolean write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { - NMSettingIP6Config *s_ip6; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip6; + NMSettingIPConfig *s_ip4; const char *value; - char *addr_key, *prefix; + char *addr_key; guint32 i, num, num4; GString *searches; - char buf[INET6_ADDRSTRLEN]; - char ipv6_defaultgw[INET6_ADDRSTRLEN]; - NMIP6Address *addr; - const struct in6_addr *ip; + NMIPAddress *addr; + const char *dns; GString *ip_str1, *ip_str2, *ip_ptr; char *route6_path; @@ -2337,7 +2269,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } - value = nm_setting_ip6_config_get_method (s_ip6); + value = nm_setting_ip_config_get_method (s_ip6); g_assert (value); if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { svSetValue (ifcfg, "IPV6INIT", "no", FALSE); @@ -2352,7 +2284,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "IPV6INIT", "yes", FALSE); svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE); svSetValue (ifcfg, "DHCPV6C", "yes", FALSE); - hostname = nm_setting_ip6_config_get_dhcp_hostname (s_ip6); + hostname = nm_setting_ip_config_get_dhcp_hostname (s_ip6); if (hostname) svSetValue (ifcfg, "DHCP_HOSTNAME", hostname, FALSE); } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { @@ -2370,62 +2302,47 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) } /* Write out IP addresses */ - num = nm_setting_ip6_config_get_num_addresses (s_ip6); + num = nm_setting_ip_config_get_num_addresses (s_ip6); ip_str1 = g_string_new (NULL); ip_str2 = g_string_new (NULL); - ipv6_defaultgw[0] = 0; for (i = 0; i < num; i++) { if (i == 0) ip_ptr = ip_str1; else ip_ptr = ip_str2; - addr = nm_setting_ip6_config_get_address (s_ip6, i); - ip = nm_ip6_address_get_address (addr); - prefix = g_strdup_printf ("%u", nm_ip6_address_get_prefix (addr)); - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf)); + addr = nm_setting_ip_config_get_address (s_ip6, i); + if (i > 1) g_string_append_c (ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */ - g_string_append (ip_ptr, buf); - g_string_append_c (ip_ptr, '/'); - g_string_append (ip_ptr, prefix); - g_free (prefix); - - /* We only support gateway for the first IP address for now */ - if (i == 0) { - ip = nm_ip6_address_get_gateway (addr); - if (!IN6_IS_ADDR_UNSPECIFIED (ip)) - inet_ntop (AF_INET6, ip, ipv6_defaultgw, sizeof (ipv6_defaultgw)); - } + g_string_append_printf (ip_ptr, "%s/%u", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); } svSetValue (ifcfg, "IPV6ADDR", ip_str1->str, FALSE); svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str, FALSE); - svSetValue (ifcfg, "IPV6_DEFAULTGW", ipv6_defaultgw, FALSE); + svSetValue (ifcfg, "IPV6_DEFAULTGW", nm_setting_ip_config_get_gateway (s_ip6), FALSE); g_string_free (ip_str1, TRUE); g_string_free (ip_str2, TRUE); /* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */ s_ip4 = nm_connection_get_setting_ip4_config (connection); - num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */ - num = nm_setting_ip6_config_get_num_dns (s_ip6); + num4 = s_ip4 ? nm_setting_ip_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */ + num = nm_setting_ip_config_get_num_dns (s_ip6); for (i = 0; i < 254; i++) { addr_key = g_strdup_printf ("DNS%d", i + num4 + 1); if (i >= num) svSetValue (ifcfg, addr_key, NULL, FALSE); else { - ip = nm_setting_ip6_config_get_dns (s_ip6, i); - - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf)); - svSetValue (ifcfg, addr_key, buf, FALSE); + dns = nm_setting_ip_config_get_dns (s_ip6, i); + svSetValue (ifcfg, addr_key, dns, FALSE); } g_free (addr_key); } /* Write out DNS domains - 'DOMAIN' key is shared for both IPv4 and IPv6 domains */ - num = nm_setting_ip6_config_get_num_dns_searches (s_ip6); + num = nm_setting_ip_config_get_num_dns_searches (s_ip6); if (num > 0) { char *ip4_domains; ip4_domains = svGetValue (ifcfg, "DOMAIN", FALSE); @@ -2433,7 +2350,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) for (i = 0; i < num; i++) { if (searches->len > 0) g_string_append_c (searches, ' '); - g_string_append (searches, nm_setting_ip6_config_get_dns_search (s_ip6, i)); + g_string_append (searches, nm_setting_ip_config_get_dns_search (s_ip6, i)); } svSetValue (ifcfg, "DOMAIN", searches->str, FALSE); g_string_free (searches, TRUE); @@ -2442,7 +2359,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) /* handle IPV6_DEFROUTE */ /* IPV6_DEFROUTE has the opposite meaning from 'never-default' */ - if (nm_setting_ip6_config_get_never_default(s_ip6)) + if (nm_setting_ip_config_get_never_default(s_ip6)) svSetValue (ifcfg, "IPV6_DEFROUTE", "no", FALSE); else svSetValue (ifcfg, "IPV6_DEFROUTE", "yes", FALSE); @@ -2451,22 +2368,22 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svSetValue (ifcfg, "IPV6_PEERROUTES", NULL, FALSE); if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { svSetValue (ifcfg, "IPV6_PEERDNS", - nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? "no" : "yes", + nm_setting_ip_config_get_ignore_auto_dns (s_ip6) ? "no" : "yes", FALSE); svSetValue (ifcfg, "IPV6_PEERROUTES", - nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? "no" : "yes", + nm_setting_ip_config_get_ignore_auto_routes (s_ip6) ? "no" : "yes", FALSE); } svSetValue (ifcfg, "IPV6_FAILURE_FATAL", - nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes", + nm_setting_ip_config_get_may_fail (s_ip6) ? "no" : "yes", FALSE); /* IPv6 Privacy Extensions */ svSetValue (ifcfg, "IPV6_PRIVACY", NULL, FALSE); svSetValue (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", NULL, FALSE); - switch (nm_setting_ip6_config_get_ip6_privacy (s_ip6)){ + switch (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))){ case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: svSetValue (ifcfg, "IPV6_PRIVACY", "no", FALSE); break; @@ -2484,7 +2401,7 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) /* Static routes go to route6- file */ route6_path = utils_get_route6_path (ifcfg->fileName); if (!route6_path) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not get route6 file path for '%s'", ifcfg->fileName); goto error; } @@ -2502,7 +2419,6 @@ error: static char * escape_id (const char *id) { - static const char const as_dash[] = "\\][|/=()!"; char *escaped = g_strdup (id); char *p = escaped; @@ -2510,7 +2426,7 @@ escape_id (const char *id) while (*p) { if (*p == ' ') *p = '_'; - else if (strchr (as_dash, *p)) + else if (strchr ("\\][|/=()!", *p)) *p = '-'; p++; } @@ -2573,7 +2489,7 @@ write_connection (NMConnection *connection, g_free (escaped); if (ifcfg_name == NULL) { - g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Failed to find usable ifcfg file name"); return FALSE; } @@ -2583,7 +2499,7 @@ write_connection (NMConnection *connection, type = nm_setting_connection_get_connection_type (s_con); if (!type) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Missing connection type!"); goto out; } @@ -2591,7 +2507,7 @@ write_connection (NMConnection *connection, if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) { // FIXME: can't write PPPoE at this time if (nm_connection_get_setting_pppoe (connection)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Can't write connection type '%s'", NM_SETTING_PPPOE_SETTING_NAME); goto out; @@ -2619,7 +2535,7 @@ write_connection (NMConnection *connection, if (!write_bridge_setting (connection, ifcfg, error)) goto out; } else { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Can't write connection type '%s'", type); goto out; } @@ -2684,7 +2600,7 @@ writer_can_write_connection (NMConnection *connection, GError **error) s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "The ifcfg-rh plugin cannot write the connection '%s' (type '%s' pppoe %d)", nm_connection_get_id (connection), nm_setting_connection_get_connection_type (s_con), diff --git a/src/settings/plugins/ifcfg-suse/Makefile.am b/src/settings/plugins/ifcfg-suse/Makefile.am index d4f1cf74..46204d7d 100644 --- a/src/settings/plugins/ifcfg-suse/Makefile.am +++ b/src/settings/plugins/ifcfg-suse/Makefile.am @@ -1,14 +1,12 @@ AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -I${top_srcdir}/src \ -I${top_srcdir}/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-suse"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DSYSCONFDIR=\"$(sysconfdir)\" @@ -19,8 +17,3 @@ libnm_settings_plugin_ifcfg_suse_la_SOURCES = \ plugin.h libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifcfg_suse_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - $(GLIB_LIBS) - diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in index 5ff5bfb2..149faa3e 100644 --- a/src/settings/plugins/ifcfg-suse/Makefile.in +++ b/src/settings/plugins/ifcfg-suse/Makefile.in @@ -130,10 +130,7 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) -am__DEPENDENCIES_1 = -libnm_settings_plugin_ifcfg_suse_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la $(am__DEPENDENCIES_1) +libnm_settings_plugin_ifcfg_suse_la_LIBADD = am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS = plugin.lo libnm_settings_plugin_ifcfg_suse_la_OBJECTS = \ $(am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS) @@ -216,6 +213,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -339,6 +338,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -358,6 +358,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -384,7 +385,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -465,15 +466,13 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -I${top_srcdir}/src \ -I${top_srcdir}/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifcfg-suse"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DSYSCONFDIR=\"$(sysconfdir)\" @@ -483,11 +482,6 @@ libnm_settings_plugin_ifcfg_suse_la_SOURCES = \ plugin.h libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifcfg_suse_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - $(GLIB_LIBS) - all: all-am .SUFFIXES: diff --git a/src/settings/plugins/ifcfg-suse/plugin.c b/src/settings/plugins/ifcfg-suse/plugin.c index d6aa79fb..a1667f64 100644 --- a/src/settings/plugins/ifcfg-suse/plugin.c +++ b/src/settings/plugins/ifcfg-suse/plugin.c @@ -22,7 +22,8 @@ * (C) Copyright 2007 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include @@ -55,17 +56,6 @@ typedef struct { char *hostname; } SCPluginIfcfgPrivate; -GQuark -ifcfg_plugin_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark"); - - return error_quark; -} - typedef void (*FileChangedFn) (gpointer user_data); typedef struct { @@ -148,7 +138,7 @@ hostname_is_dynamic (void) } static char * -hostname_read () +hostname_read (void) { GIOChannel *channel; char *hostname = NULL; diff --git a/src/settings/plugins/ifcfg-suse/plugin.h b/src/settings/plugins/ifcfg-suse/plugin.h index 4090a11e..24dbff95 100644 --- a/src/settings/plugins/ifcfg-suse/plugin.h +++ b/src/settings/plugins/ifcfg-suse/plugin.h @@ -46,7 +46,5 @@ struct _SCPluginIfcfgClass { GType sc_plugin_ifcfg_get_type (void); -GQuark ifcfg_plugin_error_quark (void); - #endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/ifnet/Makefile.am b/src/settings/plugins/ifnet/Makefile.am index a22ea557..b0cfd9a1 100644 --- a/src/settings/plugins/ifnet/Makefile.am +++ b/src/settings/plugins/ifnet/Makefile.am @@ -4,21 +4,15 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifnet"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(GUDEV_CFLAGS) \ -DSYSCONFDIR=\"$(sysconfdir)\" -DSBINDIR=\"$(sbindir)\" @@ -34,12 +28,7 @@ libnm_settings_plugin_ifnet_la_SOURCES = \ libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifnet_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - lib-ifnet-io.la\ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) +libnm_settings_plugin_ifnet_la_LIBADD = lib-ifnet-io.la lib_ifnet_io_la_SOURCES = \ net_parser.c\ @@ -49,10 +38,4 @@ lib_ifnet_io_la_SOURCES = \ net_utils.h\ net_utils.c\ wpa_parser.h\ - wpa_parser.c \ - errors.h \ - errors.c - -lib_ifnet_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) + wpa_parser.c diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in index 6a658189..11e9297f 100644 --- a/src/settings/plugins/ifnet/Makefile.in +++ b/src/settings/plugins/ifnet/Makefile.in @@ -130,20 +130,15 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) -am__DEPENDENCIES_1 = -lib_ifnet_io_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) +lib_ifnet_io_la_LIBADD = am_lib_ifnet_io_la_OBJECTS = net_parser.lo connection_parser.lo \ - net_utils.lo wpa_parser.lo errors.lo + net_utils.lo wpa_parser.lo lib_ifnet_io_la_OBJECTS = $(am_lib_ifnet_io_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libnm_settings_plugin_ifnet_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la lib-ifnet-io.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +libnm_settings_plugin_ifnet_la_DEPENDENCIES = lib-ifnet-io.la am_libnm_settings_plugin_ifnet_la_OBJECTS = nm-ifnet-connection.lo \ plugin.lo libnm_settings_plugin_ifnet_la_OBJECTS = \ @@ -266,6 +261,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -389,6 +386,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -408,6 +406,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -434,7 +433,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -516,21 +515,15 @@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifnet"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ - $(GUDEV_CFLAGS) \ -DSYSCONFDIR=\"$(sysconfdir)\" pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la @@ -542,13 +535,7 @@ libnm_settings_plugin_ifnet_la_SOURCES = \ plugin.h libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifnet_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - lib-ifnet-io.la\ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) - +libnm_settings_plugin_ifnet_la_LIBADD = lib-ifnet-io.la lib_ifnet_io_la_SOURCES = \ net_parser.c\ net_parser.h\ @@ -557,13 +544,7 @@ lib_ifnet_io_la_SOURCES = \ net_utils.h\ net_utils.c\ wpa_parser.h\ - wpa_parser.c \ - errors.h \ - errors.c - -lib_ifnet_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) + wpa_parser.c all: all-recursive @@ -659,7 +640,6 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_parser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-ifnet-connection.Plo@am__quote@ diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index 85873d5f..41baf315 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -24,27 +24,18 @@ #include #include #include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "nm-system-config-interface.h" +#include "nm-logging.h" +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" #include "net_utils.h" #include "wpa_parser.h" #include "connection_parser.h" #include "nm-ifnet-connection.h" -#include "errors.h" static char * connection_id_from_ifnet_name (const char *conn_name) @@ -52,8 +43,16 @@ connection_id_from_ifnet_name (const char *conn_name) int name_len = strlen (conn_name); /* Convert a hex-encoded conn_name (only used for wifi SSIDs) to human-readable one */ - if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) - return nm_utils_hexstr2bin (conn_name + 2, name_len - 2); + if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { + GBytes *bytes = nm_utils_hexstr2bin (conn_name); + char *buf; + + if (bytes) { + buf = g_strndup (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes)); + g_bytes_unref (bytes); + return buf; + } + } return g_strdup (conn_name); } @@ -125,7 +124,7 @@ eap_simple_reader (const char *eap_method, /* identity */ value = wpa_get_value (ssid, "identity"); if (!value) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", eap_method); return FALSE; @@ -135,7 +134,7 @@ eap_simple_reader (const char *eap_method, /* password */ value = wpa_get_value (ssid, "password"); if (!value) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_PASSWORD for EAP method '%s'.", eap_method); return FALSE; @@ -177,7 +176,7 @@ eap_tls_reader (const char *eap_method, /* identity */ value = wpa_get_value (ssid, "identity"); if (!value) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", eap_method); return FALSE; @@ -208,11 +207,11 @@ eap_tls_reader (const char *eap_method, /* Private key password */ privkey_password = wpa_get_value (ssid, - phase2 ? "private_key_passwd2" : + phase2 ? "private_key2_passwd" : "private_key_passwd"); if (!privkey_password) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : "IEEE_8021X_PRIVATE_KEY_PASSWORD", eap_method); @@ -222,7 +221,7 @@ eap_tls_reader (const char *eap_method, /* The private key itself */ privkey = get_cert (ssid, phase2 ? "private_key2" : "private_key", basepath); if (!privkey) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY", eap_method); @@ -255,7 +254,7 @@ eap_tls_reader (const char *eap_method, || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) { client_cert = get_cert (ssid, phase2 ? "client_cert2" : "client_cert", basepath); if (!client_cert) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT", eap_method); @@ -323,7 +322,7 @@ eap_peap_reader (const char *eap_method, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_PEAP_VERSION value '%s'", peapver); goto done; @@ -337,7 +336,7 @@ eap_peap_reader (const char *eap_method, inner_auth = wpa_get_value (ssid, "phase2"); if (!inner_auth) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_INNER_AUTH_METHODS."); goto done; } @@ -358,7 +357,7 @@ eap_peap_reader (const char *eap_method, if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, basepath, error)) goto done; } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", *iter); goto done; @@ -374,7 +373,7 @@ eap_peap_reader (const char *eap_method, } if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No valid IEEE_8021X_INNER_AUTH_METHODS found."); goto done; } @@ -423,7 +422,7 @@ eap_ttls_reader (const char *eap_method, tmp = wpa_get_value (ssid, "phase2"); if (!tmp) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_INNER_AUTH_METHODS."); goto done; } @@ -458,7 +457,7 @@ eap_ttls_reader (const char *eap_method, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, pos, NULL); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.", *iter); goto done; @@ -499,20 +498,20 @@ guess_connection_type (const char *conn_name) /* Reading mac address for setting connection option. * Unmanaged device mac address is required by NetworkManager*/ static gboolean -read_mac_address (const char *conn_name, GByteArray **array, GError **error) +read_mac_address (const char *conn_name, const char **mac, GError **error) { const char *value = ifnet_get_data (conn_name, "mac"); if (!value || !strlen (value)) return TRUE; - *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); - if (!*array) { - g_set_error (error, ifnet_plugin_error_quark (), 0, - "The MAC address '%s' was invalid.", value); + if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "The MAC address '%s' was invalid.", value); return FALSE; } + *mac = value; return TRUE; } @@ -521,7 +520,7 @@ make_wired_connection_setting (NMConnection *connection, const char *conn_name, GError **error) { - GByteArray *mac = NULL; + const char *mac = NULL; NMSettingWired *s_wired = NULL; const char *value = NULL; @@ -545,7 +544,6 @@ make_wired_connection_setting (NMConnection *connection, if (mac) { g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); } } else { g_object_unref (s_wired); @@ -555,56 +553,56 @@ make_wired_connection_setting (NMConnection *connection, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } -/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, - * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/ +/* add NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, + * NM_SETTING_IP_CONFIG_DHCP_CLIENT_ID in future*/ static void make_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) { - NMSettingIP4Config *ip4_setting = - NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + NMSettingIPConfig *ip4_setting = + NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); const char *value, *method = NULL; gboolean is_static_block = is_static_ip4 (conn_name); ip_block *iblock = NULL; /* set dhcp options (dhcp_xxx) */ value = ifnet_get_data (conn_name, "dhcp"); - g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, value + g_object_set (ip4_setting, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, value && strstr (value, "nodns") ? TRUE : FALSE, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, value + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, value && strstr (value, "nogateway") ? TRUE : FALSE, NULL); if (!is_static_block) { method = ifnet_get_data (conn_name, "config"); if (!method){ - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown config for %s", conn_name); g_object_unref (ip4_setting); return; } if (strstr (method, "dhcp")) g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); else if (strstr (method, "autoip")) { g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); return; } else if (strstr (method, "shared")) { g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, NULL); nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); return; } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown config for %s", conn_name); g_object_unref (ip4_setting); return; @@ -613,7 +611,7 @@ make_ip4_setting (NMConnection *connection, }else { iblock = convert_ip4_config_block (conn_name); if (!iblock) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ifnet plugin: can't aquire ip configuration for %s", conn_name); g_object_unref (ip4_setting); @@ -622,29 +620,32 @@ make_ip4_setting (NMConnection *connection, /************** add all ip settings to the connection**********/ while (iblock) { ip_block *current_iblock; - NMIP4Address *ip4_addr = nm_ip4_address_new (); - - nm_ip4_address_set_address (ip4_addr, iblock->ip); - nm_ip4_address_set_prefix (ip4_addr, - nm_utils_ip4_netmask_to_prefix - (iblock->netmask)); - /* currently all the IPs has the same gateway */ - nm_ip4_address_set_gateway (ip4_addr, iblock->gateway); - if (iblock->gateway) + NMIPAddress *ip4_addr; + GError *local = NULL; + + ip4_addr = nm_ip_address_new (AF_INET, iblock->ip, iblock->prefix, &local); + if (iblock->next_hop) g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, NULL); - if (!nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) - nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP4 address"); - nm_ip4_address_unref (ip4_addr); + + if (ip4_addr) { + if (!nm_setting_ip_config_add_address (ip4_setting, ip4_addr)) + nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP4 address"); + nm_ip_address_unref (ip4_addr); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); + g_clear_error (&local); + } + current_iblock = iblock; iblock = iblock->next; destroy_ip_block (current_iblock); } g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), NULL); } @@ -655,7 +656,7 @@ make_ip4_setting (NMConnection *connection, get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); if (dhcp_hostname) { g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, dhcp_hostname, NULL); nm_log_info (LOGD_SETTINGS, "DHCP hostname: %s", dhcp_hostname); g_free (dhcp_hostname); @@ -686,7 +687,7 @@ make_ip4_setting (NMConnection *connection, for (item = searches; *item; item++) { if (strlen (*item)) { - if (!nm_setting_ip4_config_add_dns_search (ip4_setting, *item)) + if (!nm_setting_ip_config_add_dns_search (ip4_setting, *item)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *item); } } @@ -700,34 +701,34 @@ make_ip4_setting (NMConnection *connection, ip_block *current_iblock = iblock; const char *metric_str; char *stripped; - long int metric; - NMIP4Route *route = nm_ip4_route_new (); - - nm_ip4_route_set_dest (route, iblock->ip); - nm_ip4_route_set_next_hop (route, iblock->gateway); - nm_ip4_route_set_prefix (route, - nm_utils_ip4_netmask_to_prefix - (iblock->netmask)); + gint64 metric; + NMIPRoute *route; + GError *local = NULL; + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { - metric = strtol (metric_str, NULL, 10); - nm_ip4_route_set_metric (route, (guint32) metric); + metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); } else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { stripped = g_strdup (metric_str); strip_string (stripped, '"'); - metric = strtol (metric_str, NULL, 10); - nm_ip4_route_set_metric (route, - (guint32) metric); + metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); g_free (stripped); - } + } else + metric = -1; } - if (!nm_setting_ip4_config_add_route (ip4_setting, route)) - nm_log_warn (LOGD_SETTINGS, "duplicate IP4 route"); - nm_log_info (LOGD_SETTINGS, "new IP4 route:%d\n", iblock->ip); - - nm_ip4_route_unref (route); + route = nm_ip_route_new (AF_INET, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); + if (route) { + if (nm_setting_ip_config_add_route (ip4_setting, route)) + nm_log_info (LOGD_SETTINGS, "new IP4 route:%s\n", iblock->ip); + else + nm_log_warn (LOGD_SETTINGS, "duplicate IP4 route"); + nm_ip_route_unref (route); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); + g_clear_error (&local); + } current_iblock = iblock; iblock = iblock->next; @@ -743,17 +744,17 @@ make_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) { - NMSettingIP6Config *s_ip6 = NULL; + NMSettingIPConfig *s_ip6 = NULL; gboolean is_static_block = is_static_ip6 (conn_name); // used to disable IPv6 gboolean ipv6_enabled = FALSE; gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; const char *value; - ip6_block *iblock; + ip_block *iblock; gboolean never_default = !has_default_ip6_route (conn_name); - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); value = ifnet_get_data (conn_name, "enable_ipv6"); if (value && is_true (value)) @@ -763,7 +764,7 @@ make_ip6_setting (NMConnection *connection, // Currently only Manual and DHCP are supported if (!ipv6_enabled) { g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); goto done; } else if (!is_static_block) { @@ -780,91 +781,98 @@ make_ip6_setting (NMConnection *connection, nm_log_info (LOGD_SETTINGS, "IPv6 for %s enabled, using %s", conn_name, method); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, method, - NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, FALSE, - NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, FALSE, - NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, NULL); + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, FALSE, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, FALSE, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, NULL); /* Make manual settings */ if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - ip6_block *current_iblock; + ip_block *current_iblock; iblock = convert_ip6_config_block (conn_name); if (!iblock) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ifnet plugin: can't aquire ip6 configuration for %s", conn_name); goto error; } /* add all IPv6 addresses */ while (iblock) { - NMIP6Address *ip6_addr = nm_ip6_address_new (); - - nm_ip6_address_set_address (ip6_addr, iblock->ip); - nm_ip6_address_set_prefix (ip6_addr, iblock->prefix); - if (nm_setting_ip6_config_add_address (s_ip6, ip6_addr)) { - nm_log_info (LOGD_SETTINGS, "ipv6 addresses count: %d", - nm_setting_ip6_config_get_num_addresses (s_ip6)); + NMIPAddress *ip6_addr; + GError *local = NULL; + + ip6_addr = nm_ip_address_new (AF_INET6, iblock->ip, iblock->prefix, &local); + if (ip6_addr) { + if (nm_setting_ip_config_add_address (s_ip6, ip6_addr)) { + nm_log_info (LOGD_SETTINGS, "ipv6 addresses count: %d", + nm_setting_ip_config_get_num_addresses (s_ip6)); + } else { + nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP6 address"); + } + nm_ip_address_unref (ip6_addr); } else { - nm_log_warn (LOGD_SETTINGS, "ignoring duplicate IP4 address"); + nm_log_warn (LOGD_SETTINGS, " ignoring invalid address entry: %s", local->message); + g_clear_error (&local); } - nm_ip6_address_unref (ip6_addr); + current_iblock = iblock; iblock = iblock->next; - destroy_ip6_block (current_iblock); + destroy_ip_block (current_iblock); } } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { /* - autoconf or DHCPv6 stuff goes here */ } - // DNS Servers, set NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS TRUE here + // DNS Servers, set NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS TRUE here set_ip6_dns_servers (s_ip6, conn_name); - /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */ + /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIPConfig */ // Add routes iblock = convert_ip6_routes_block (conn_name); if (iblock) - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, TRUE, NULL); /* Add all IPv6 routes */ while (iblock) { - ip6_block *current_iblock = iblock; + ip_block *current_iblock = iblock; const char *metric_str; char *stripped; - long int metric = 1; - NMIP6Route *route = nm_ip6_route_new (); + gint64 metric; + NMIPRoute *route; + GError *local = NULL; - nm_ip6_route_set_dest (route, iblock->ip); - nm_ip6_route_set_next_hop (route, iblock->next_hop); - nm_ip6_route_set_prefix (route, iblock->prefix); /* metric is not per routes configuration right now * global metric is also supported (metric="x") */ - if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { - metric = strtol (metric_str, NULL, 10); - nm_ip6_route_set_metric (route, (guint32) metric); - } else { + if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) + metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); + else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { stripped = g_strdup (metric_str); strip_string (stripped, '"'); - metric = strtol (metric_str, NULL, 10); - nm_ip6_route_set_metric (route, - (guint32) metric); + metric = nm_utils_ascii_str_to_int64 (metric_str, 10, 0, G_MAXUINT32, -1); g_free (stripped); } else - nm_ip6_route_set_metric (route, (guint32) 1); + metric = 1; } - if (nm_setting_ip6_config_add_route (s_ip6, route)) - nm_log_info (LOGD_SETTINGS, " new IP6 route"); - else - nm_log_warn (LOGD_SETTINGS, " duplicate IP6 route"); - nm_ip6_route_unref (route); + route = nm_ip_route_new (AF_INET6, iblock->ip, iblock->prefix, iblock->next_hop, metric, &local); + if (route) { + if (nm_setting_ip_config_add_route (s_ip6, route)) + nm_log_info (LOGD_SETTINGS, " new IP6 route"); + else + nm_log_warn (LOGD_SETTINGS, " duplicate IP6 route"); + nm_ip_route_unref (route); + } else { + nm_log_warn (LOGD_SETTINGS, " ignoring invalid route entry: %s", local->message); + g_clear_error (&local); + } current_iblock = iblock; iblock = iblock->next; - destroy_ip6_block (current_iblock); + destroy_ip_block (current_iblock); } done: @@ -882,7 +890,7 @@ make_wireless_connection_setting (const char *conn_name, NMSetting8021x **s_8021x, GError **error) { - GByteArray *array, *mac = NULL; + const char *mac = NULL; NMSettingWireless *wireless_setting = NULL; gboolean adhoc = FALSE; const char *value; @@ -904,8 +912,6 @@ make_wireless_connection_setting (const char *conn_name, g_object_set (wireless_setting, NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); - g_byte_array_free (mac, TRUE); - } } else { g_object_unref (wireless_setting); @@ -914,51 +920,41 @@ make_wireless_connection_setting (const char *conn_name, /* handle ssid (hex and ascii) */ if (conn_name) { + GBytes *bytes; gsize ssid_len = 0, value_len = strlen (conn_name); - const char *p; - char *tmp, *converted = NULL; ssid_len = value_len; if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { /* Hex representation */ if (value_len % 2) { - g_set_error (error, ifnet_plugin_error_quark (), - 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid SSID '%s' size (looks like hex but length not multiple of 2)", conn_name); goto error; } - // ignore "0x" - p = conn_name + 2; - if (!is_hex (p)) { - g_set_error (error, - ifnet_plugin_error_quark (), - 0, - "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)", - conn_name, *p); - goto error; + bytes = nm_utils_hexstr2bin (conn_name); + if (!bytes) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid SSID '%s' (looks like hex SSID but isn't)", + conn_name); + goto error; } - tmp = nm_utils_hexstr2bin (p, value_len - 2); - ssid_len = (value_len - 2) / 2; - converted = g_malloc0 (ssid_len + 1); - memcpy (converted, tmp, ssid_len); - g_free (tmp); - } + } else + bytes = g_bytes_new (conn_name, value_len); + ssid_len = g_bytes_get_size (bytes); if (ssid_len > 32 || ssid_len == 0) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)", conn_name, ssid_len); goto error; } - array = g_byte_array_sized_new (ssid_len); - g_byte_array_append (array, (const guint8 *) (converted ? converted : conn_name), ssid_len); - g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, array, NULL); - g_byte_array_free (array, TRUE); - g_free (converted); + + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, bytes, NULL); + g_bytes_unref (bytes); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing SSID"); goto error; } @@ -980,18 +976,14 @@ make_wireless_connection_setting (const char *conn_name, /* BSSID setting */ value = wpa_get_value (conn_name, "bssid"); if (value) { - GByteArray *bssid; - - bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); - if (!bssid) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid BSSID '%s'", value); goto error; } g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, - bssid, NULL); - g_byte_array_free (bssid, TRUE); + value, NULL); } @@ -1043,7 +1035,7 @@ make_leap_setting (const char *ssid, GError **error) value = wpa_get_value (ssid, "identity"); if (!value || !strlen (value)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing LEAP identity"); goto error; } @@ -1085,8 +1077,8 @@ add_one_wep_key (const char *ssid, if (strlen (value) == 10 || strlen (value) == 26) { /* Hexadecimal WEP key */ if (!is_hex (value)) { - g_set_error (error, ifnet_plugin_error_quark (), - 0, "Invalid hexadecimal WEP key."); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hexadecimal WEP key."); goto out; } converted = g_strdup (value); @@ -1097,17 +1089,17 @@ add_one_wep_key (const char *ssid, char *p = strip_string (tmp, '"'); if (!is_ascii (p)) { - g_set_error (error, ifnet_plugin_error_quark (), - 0, "Invalid ASCII WEP passphrase."); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid ASCII WEP passphrase."); g_free (tmp); goto out; } - converted = nm_utils_bin2hexstr (tmp, strlen (tmp), strlen (tmp) * 2); + converted = nm_utils_bin2hexstr (tmp, strlen (tmp), -1); g_free (tmp); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WEP key length. Key: %s", value); goto out; } @@ -1161,7 +1153,7 @@ make_wep_setting (const char *ssid, GError **error) default_key_idx, NULL); nm_log_info (LOGD_SETTINGS, "Default key index: %d", default_key_idx); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid default WEP key '%s'", value); goto error; } @@ -1173,19 +1165,19 @@ make_wep_setting (const char *ssid, GError **error) /* If there's a default key, ensure that key exists */ if ((default_key_idx == 1) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Default WEP key index was 2, but no valid KEY2 exists."); goto error; } else if ((default_key_idx == 2) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Default WEP key index was 3, but no valid KEY3 exists."); goto error; } else if ((default_key_idx == 3) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Default WEP key index was 4, but no valid KEY4 exists."); goto error; } @@ -1204,7 +1196,7 @@ make_wep_setting (const char *ssid, GError **error) "shared", NULL); nm_log_info (LOGD_SETTINGS, "WEP: Use shared system authentication"); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WEP authentication algorithm '%s'", auth_alg); goto error; @@ -1218,7 +1210,7 @@ make_wep_setting (const char *ssid, GError **error) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3) && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) { if (auth_alg && !strcmp (auth_alg, "shared")) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "WEP Shared Key authentication is invalid for " "unencrypted connections."); goto error; @@ -1242,7 +1234,7 @@ parse_wpa_psk (const char *psk, GError **error) gboolean quoted = FALSE; if (!psk) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing WPA_PSK for WPA-PSK key management"); return NULL; } @@ -1258,9 +1250,8 @@ parse_wpa_psk (const char *psk, GError **error) if (!quoted && (strlen (psk) == 64)) { /* Verify the hex PSK; 64 digits */ if (!is_hex (psk)) { - g_set_error (error, ifnet_plugin_error_quark (), - 0, - "Invalid WPA_PSK (contains non-hexadecimal characters)"); + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid WPA_PSK (contains non-hexadecimal characters)"); goto out; } hashed = g_strdup (psk); @@ -1271,7 +1262,7 @@ parse_wpa_psk (const char *psk, GError **error) /* Length check */ if (strlen (stripped) < 8 || strlen (stripped) > 63) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WPA_PSK (passphrases must be between " "8 and 63 characters long (inclusive))"); g_free (stripped); @@ -1283,7 +1274,7 @@ parse_wpa_psk (const char *psk, GError **error) } if (!hashed) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WPA_PSK (doesn't look like a passphrase or hex key)"); goto out; } @@ -1367,7 +1358,7 @@ fill_8021x (const char *ssid, value = wpa_get_value (ssid, "eap"); if (!value) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IEEE_8021X_EAP_METHODS for key management '%s'", key_mgmt); return NULL; @@ -1383,7 +1374,7 @@ fill_8021x (const char *ssid, char *lower = NULL; lower = g_ascii_strdown (*iter, -1); - while (eap->method && !found) { + while (eap->method) { if (strcmp (eap->method, lower)) goto next; @@ -1404,6 +1395,7 @@ fill_8021x (const char *ssid, } nm_setting_802_1x_add_eap_method (s_8021x, lower); found = TRUE; + break; next: eap++; @@ -1417,7 +1409,7 @@ fill_8021x (const char *ssid, g_strfreev (list); if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No valid EAP methods found in IEEE_8021X_EAP_METHODS."); goto error; } @@ -1441,7 +1433,7 @@ make_wpa_setting (const char *ssid, gboolean adhoc = FALSE; if (!exist_ssid (ssid)) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No security info found for ssid: %s", ssid); return NULL; } @@ -1493,7 +1485,7 @@ make_wpa_setting (const char *ssid, "wpa-psk", NULL); } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) { if (adhoc) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", value); goto error; @@ -1507,7 +1499,7 @@ make_wpa_setting (const char *ssid, lower, NULL); g_free (lower); } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Unknown wireless KEY_MGMT type '%s'", value); goto error; } @@ -1558,7 +1550,7 @@ make_wireless_security_setting (const char *conn_name, } if (!wsec) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Can't handle security information for ssid: %s", conn_name); } @@ -1574,8 +1566,8 @@ make_pppoe_connection_setting (NMConnection *connection, const char *conn_name, GError **error) { - NMSettingPPPOE *s_pppoe; - NMSettingPPP *s_ppp; + NMSettingPppoe *s_pppoe; + NMSettingPpp *s_ppp; const char *value; s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ()); @@ -1583,7 +1575,7 @@ make_pppoe_connection_setting (NMConnection *connection, /* username */ value = ifnet_get_data (conn_name, "username"); if (!value) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "ppp requires at lease a username"); return; } @@ -1599,7 +1591,7 @@ make_pppoe_connection_setting (NMConnection *connection, nm_connection_add_setting (connection, NM_SETTING (s_pppoe)); /* PPP setting */ - s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + s_ppp = (NMSettingPpp *) nm_setting_ppp_new (); nm_connection_add_setting (connection, NM_SETTING (s_ppp)); } @@ -1618,7 +1610,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, gchar *id, *uuid; gboolean success = FALSE; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); setting = nm_connection_get_setting_connection (connection); if (!setting) { setting = NM_SETTING_CONNECTION (nm_setting_connection_new ()); @@ -1637,7 +1629,7 @@ ifnet_update_connection_from_config_block (const char *conn_name, id = connection_id_from_ifnet_name (conn_name); uuid = g_strdup (ifnet_get_data (conn_name, "uuid")); if (!uuid) - uuid = nm_utils_uuid_generate_from_string (id); + uuid = nm_utils_uuid_generate_from_string (id, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type, @@ -1727,7 +1719,7 @@ error: typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x * setting); typedef const char *(*PathFunc) (NMSetting8021x * setting); -typedef const GByteArray *(*BlobFunc) (NMSetting8021x * setting); +typedef GBytes *(*BlobFunc) (NMSetting8021x * setting); typedef struct ObjectType { const char *setting_key; @@ -1813,13 +1805,13 @@ static const ObjectType phase2_p12_type = { static gboolean write_object (NMSetting8021x *s_8021x, const char *conn_name, - const GByteArray *override_data, + GBytes *override_data, const ObjectType *objtype, GError **error) { NMSetting8021xCKScheme scheme; const char *path = NULL; - const GByteArray *blob = NULL; + GBytes *blob = NULL; g_return_val_if_fail (conn_name != NULL, FALSE); g_return_val_if_fail (objtype != NULL, FALSE); @@ -1867,8 +1859,8 @@ write_8021x_certs (NMSetting8021x *s_8021x, char *password = NULL; const ObjectType *otype = NULL; gboolean is_pkcs12 = FALSE, success = FALSE; - const GByteArray *blob = NULL; - GByteArray *enc_key = NULL; + GBytes *blob = NULL; + GBytes *enc_key = NULL; gchar *generated_pw = NULL; /* CA certificate */ @@ -1915,13 +1907,17 @@ write_8021x_certs (NMSetting8021x *s_8021x, * private key file, it'll be encrypted, so we don't need to re-encrypt. */ if (blob && !is_pkcs12) { + GByteArray *tmp_enc_key; + /* Encrypt the unencrypted private key with the fake password */ - enc_key = - nm_utils_rsa_key_encrypt (blob, password, &generated_pw, - error); - if (!enc_key) + tmp_enc_key = + nm_utils_rsa_key_encrypt (g_bytes_get_data (blob, NULL), g_bytes_get_size (blob), + password, &generated_pw, error); + if (!tmp_enc_key) goto out; + enc_key = g_byte_array_free_to_bytes (tmp_enc_key); + if (generated_pw) password = generated_pw; } @@ -1932,7 +1928,7 @@ write_8021x_certs (NMSetting8021x *s_8021x, goto out; if (phase2) - wpa_set_data (conn_name, "private_key_passwd2", password); + wpa_set_data (conn_name, "private_key2_passwd", password); else wpa_set_data (conn_name, "private_key_passwd", password); @@ -1958,8 +1954,8 @@ out: g_free (generated_pw); } if (enc_key) { - memset (enc_key->data, 0, enc_key->len); - g_byte_array_free (enc_key, TRUE); + memset ((gpointer) g_bytes_get_data (enc_key, NULL), 0, g_bytes_get_size (enc_key)); + g_bytes_unref (enc_key); } return success; } @@ -2073,7 +2069,7 @@ write_wireless_security_setting (NMConnection * connection, s_wsec = nm_connection_get_setting_wireless_security (connection); if (!s_wsec) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); return FALSE; @@ -2230,8 +2226,10 @@ write_wireless_setting (NMConnection *connection, GError **error) { NMSettingWireless *s_wireless; - const GByteArray *ssid, *mac, *bssid; - const char *mode; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; + const char *mac, *bssid, *mode; char buf[33]; guint32 mtu, i; gboolean adhoc = FALSE, hex_ssid = FALSE; @@ -2239,7 +2237,7 @@ write_wireless_setting (NMConnection *connection, s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; @@ -2247,13 +2245,14 @@ write_wireless_setting (NMConnection *connection, ssid = nm_setting_wireless_get_ssid (s_wireless); if (!ssid) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; } - if (!ssid->len || ssid->len > 32) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + ssid_data = g_bytes_get_data (ssid, &ssid_len); + if (!ssid_len || ssid_len > 32) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME); return FALSE; @@ -2263,8 +2262,8 @@ write_wireless_setting (NMConnection *connection, * the hex notation of the SSID instead. (Because openrc doesn't * support these characters, see bug #356337) */ - for (i = 0; i < ssid->len; i++) { - if (!g_ascii_isalnum (ssid->data[i])) { + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isalnum (ssid_data[i])) { hex_ssid = TRUE; break; } @@ -2274,16 +2273,16 @@ write_wireless_setting (NMConnection *connection, GString *str; /* Hex SSIDs don't get quoted */ - str = g_string_sized_new (ssid->len * 2 + 3); + str = g_string_sized_new (ssid_len * 2 + 3); g_string_append (str, "0x"); - for (i = 0; i < ssid->len; i++) - g_string_append_printf (str, "%02X", ssid->data[i]); + for (i = 0; i < ssid_len; i++) + g_string_append_printf (str, "%02X", ssid_data[i]); update_wireless_ssid (connection, conn_name, str->str, hex_ssid); ssid_str = g_string_free (str, FALSE); } else { /* Printable SSIDs get quoted */ memset (buf, 0, sizeof (buf)); - memcpy (buf, ssid->data, ssid->len); + memcpy (buf, ssid_data, ssid_len); g_strstrip (buf); update_wireless_ssid (connection, conn_name, buf, hex_ssid); ssid_str = g_strdup (buf); @@ -2291,11 +2290,8 @@ write_wireless_setting (NMConnection *connection, ifnet_set_data (ssid_str, "mac", NULL); mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac) { - tmp = nm_utils_hwaddr_ntoa_len (mac->data, mac->len); - ifnet_set_data (ssid_str, "mac", tmp); - g_free (tmp); - } + if (mac) + ifnet_set_data (ssid_str, "mac", mac); ifnet_set_data (ssid_str, "mtu", NULL); mtu = nm_setting_wireless_get_mtu (s_wireless); @@ -2320,11 +2316,8 @@ write_wireless_setting (NMConnection *connection, wpa_set_data (ssid_str, "bssid", NULL); bssid = nm_setting_wireless_get_bssid (s_wireless); - if (bssid) { - tmp = nm_utils_hwaddr_ntoa_len (bssid->data, bssid->len); - wpa_set_data (ssid_str, "bssid", tmp); - g_free (tmp); - } + if (bssid) + wpa_set_data (ssid_str, "bssid", bssid); if (nm_connection_get_setting_wireless_security (connection)) { if (!write_wireless_security_setting @@ -2345,13 +2338,13 @@ write_wired_setting (NMConnection *connection, GError **error) { NMSettingWired *s_wired; - const GByteArray *mac; + const char *mac; char *tmp; guint32 mtu; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME); return FALSE; @@ -2359,11 +2352,8 @@ write_wired_setting (NMConnection *connection, ifnet_set_data (conn_name, "mac", NULL); mac = nm_setting_wired_get_mac_address (s_wired); - if (mac) { - tmp = nm_utils_hwaddr_ntoa_len (mac->data, mac->len); - ifnet_set_data (conn_name, "mac", tmp); - g_free (tmp); - } + if (mac) + ifnet_set_data (conn_name, "mac", mac); ifnet_set_data (conn_name, "mtu", NULL); mtu = nm_setting_wired_get_mtu (s_wired); @@ -2381,62 +2371,45 @@ write_wired_setting (NMConnection *connection, static gboolean write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) { - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; const char *value; - char *tmp; guint32 i, num; GString *searches; GString *ips; GString *routes; GString *dns; - gboolean has_def_route = FALSE; gboolean success = FALSE; s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing '%s' setting", NM_SETTING_IP4_CONFIG_SETTING_NAME); return FALSE; } routes = g_string_new (NULL); - value = nm_setting_ip4_config_get_method (s_ip4); + value = nm_setting_ip_config_get_method (s_ip4); g_assert (value); if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - num = nm_setting_ip4_config_get_num_addresses (s_ip4); + num = nm_setting_ip_config_get_num_addresses (s_ip4); ips = g_string_new (NULL); /* IPv4 addresses */ for (i = 0; i < num; i++) { - char buf[INET_ADDRSTRLEN + 1]; - NMIP4Address *addr; - guint32 ip; - - addr = nm_setting_ip4_config_get_address (s_ip4, i); - - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_address (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], - sizeof (buf)); - g_string_append_printf (ips, "\"%s", &buf[0]); - - tmp = - g_strdup_printf ("%u", - nm_ip4_address_get_prefix (addr)); - g_string_append_printf (ips, "/%s\" ", tmp); - g_free (tmp); + NMIPAddress *addr; + + addr = nm_setting_ip_config_get_address (s_ip4, i); + + g_string_append_printf (ips, "\"%s/%u", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); /* only the first gateway will be written */ - if (!has_def_route && nm_ip4_address_get_gateway (addr)) { - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_address_get_gateway (addr); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], - sizeof (buf)); + if (i == 0 && nm_setting_ip_config_get_gateway (s_ip4)) { g_string_append_printf (routes, - "\"default via %s\" ", - &buf[0]); - has_def_route = TRUE; + "\"default via %s\" ", + nm_setting_ip_config_get_gateway (s_ip4)); } } ifnet_set_data (conn_name, "config", ips->str); @@ -2449,19 +2422,14 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err ifnet_set_data (conn_name, "config", "dhcp"); /* DNS Servers */ - num = nm_setting_ip4_config_get_num_dns (s_ip4); + num = nm_setting_ip_config_get_num_dns (s_ip4); if (num > 0) { dns = g_string_new (NULL); for (i = 0; i < num; i++) { - char buf[INET_ADDRSTRLEN + 1]; - guint32 ip; - - ip = nm_setting_ip4_config_get_dns (s_ip4, i); + const char *ip; - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], - sizeof (buf)); - g_string_append_printf (dns, " %s", buf); + ip = nm_setting_ip_config_get_dns (s_ip4, i); + g_string_append_printf (dns, " %s", ip); } ifnet_set_data (conn_name, "dns_servers", dns->str); g_string_free (dns, TRUE); @@ -2469,14 +2437,14 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err ifnet_set_data (conn_name, "dns_servers", NULL); /* DNS Searches */ - num = nm_setting_ip4_config_get_num_dns_searches (s_ip4); + num = nm_setting_ip_config_get_num_dns_searches (s_ip4); if (num > 0) { searches = g_string_new (NULL); for (i = 0; i < num; i++) { if (i > 0) g_string_append_c (searches, ' '); g_string_append (searches, - nm_setting_ip4_config_get_dns_search + nm_setting_ip_config_get_dns_search (s_ip4, i)); } ifnet_set_data (conn_name, "dns_search", searches->str); @@ -2485,12 +2453,12 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err ifnet_set_data (conn_name, "dns_search", NULL); /* FIXME Will be implemented when configuration supports it if (!strcmp(value, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - value = nm_setting_ip4_config_get_dhcp_hostname(s_ip4); + value = nm_setting_ip_config_get_dhcp_hostname(s_ip4); if (value) ifnet_set_data(conn_name, "DHCP_HOSTNAME", value, FALSE); - value = nm_setting_ip4_config_get_dhcp_client_id(s_ip4); + value = nm_setting_ip_config_get_dhcp_client_id(s_ip4); if (value) ifnet_set_data(conn_name, "DHCP_CLIENT_ID", value, FALSE); @@ -2498,32 +2466,22 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err */ /* Static routes */ - num = nm_setting_ip4_config_get_num_routes (s_ip4); + num = nm_setting_ip_config_get_num_routes (s_ip4); if (num > 0) { for (i = 0; i < num; i++) { - char buf[INET_ADDRSTRLEN + 1]; - NMIP4Route *route; - guint32 ip; - - route = nm_setting_ip4_config_get_route (s_ip4, i); - - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_route_get_dest (route); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], - sizeof (buf)); - g_string_append_printf (routes, "\"%s", buf); - - tmp = - g_strdup_printf ("%u", - nm_ip4_route_get_prefix (route)); - g_string_append_printf (routes, "/%s via ", tmp); - g_free (tmp); + NMIPRoute *route; + const char *next_hop; + + route = nm_setting_ip_config_get_route (s_ip4, i); + + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "0.0.0.0"; - memset (buf, 0, sizeof (buf)); - ip = nm_ip4_route_get_next_hop (route); - inet_ntop (AF_INET, (const void *) &ip, &buf[0], - sizeof (buf)); - g_string_append_printf (routes, "%s\" ", buf); + g_string_append_printf (routes, "\"%s/%u via %s\" ", + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop); } } if (routes->len > 0) @@ -2538,19 +2496,16 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err } static gboolean -write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **error) +write_route6_file (NMSettingIPConfig *s_ip6, const char *conn_name, GError **error) { - char dest[INET6_ADDRSTRLEN + 1]; - char next_hop[INET6_ADDRSTRLEN + 1]; - NMIP6Route *route; - const struct in6_addr *ip; - guint32 prefix; + NMIPRoute *route; + const char *next_hop; guint32 i, num; GString *routes_string; const char *old_routes; g_return_val_if_fail (s_ip6 != NULL, FALSE); - num = nm_setting_ip6_config_get_num_routes (s_ip6); + num = nm_setting_ip_config_get_num_routes (s_ip6); if (num == 0) { return TRUE; } @@ -2560,22 +2515,16 @@ write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **er if (old_routes) g_string_append (routes_string, "\" "); for (i = 0; i < num; i++) { - route = nm_setting_ip6_config_get_route (s_ip6, i); + route = nm_setting_ip_config_get_route (s_ip6, i); - memset (dest, 0, sizeof (dest)); - ip = nm_ip6_route_get_dest (route); - inet_ntop (AF_INET6, (const void *) ip, &dest[0], - sizeof (dest)); - - prefix = nm_ip6_route_get_prefix (route); - - memset (next_hop, 0, sizeof (next_hop)); - ip = nm_ip6_route_get_next_hop (route); - inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], - sizeof (next_hop)); + next_hop = nm_ip_route_get_next_hop (route); + if (!next_hop) + next_hop = "::"; g_string_append_printf (routes_string, "\"%s/%u via %s\" ", - dest, prefix, next_hop); + nm_ip_route_get_dest (route), + nm_ip_route_get_prefix (route), + next_hop); } if (num > 0) ifnet_set_data (conn_name, "routes", routes_string->str); @@ -2587,24 +2536,21 @@ write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **er static gboolean write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) { - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; const char *value; - char *prefix; guint32 i, num; GString *searches; - char buf[INET6_ADDRSTRLEN + 1]; - NMIP6Address *addr; - const struct in6_addr *ip; + NMIPAddress *addr; s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!s_ip6) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME); return FALSE; } - value = nm_setting_ip6_config_get_method (s_ip6); + value = nm_setting_ip_config_get_method (s_ip6); g_assert (value); if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { ifnet_set_data (conn_name, "enable_ipv6", "false"); @@ -2638,22 +2584,16 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err if (!config) config = ""; - num = nm_setting_ip6_config_get_num_addresses (s_ip6); + num = nm_setting_ip_config_get_num_addresses (s_ip6); /* IPv6 addresses */ ip_str = g_string_new (NULL); for (i = 0; i < num; i++) { - addr = nm_setting_ip6_config_get_address (s_ip6, i); - ip = nm_ip6_address_get_address (addr); - prefix = - g_strdup_printf ("%u", - nm_ip6_address_get_prefix (addr)); - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET6, (const void *) ip, buf, - sizeof (buf)); - g_string_append_printf (ip_str, "\"%s/", buf); - g_string_append_printf (ip_str, "%s\" ", prefix); - g_free (prefix); + addr = nm_setting_ip_config_get_address (s_ip6, i); + + g_string_append_printf (ip_str, "\"%s/%u\"", + nm_ip_address_get_address (addr), + nm_ip_address_get_prefix (addr)); } tmp = g_strdup_printf ("%s\" %s", config, ip_str->str); ifnet_set_data (conn_name, "config", tmp); @@ -2662,22 +2602,20 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err } /* DNS Servers */ - num = nm_setting_ip6_config_get_num_dns (s_ip6); + num = nm_setting_ip_config_get_num_dns (s_ip6); if (num > 0) { const char *dns_servers = ifnet_get_data (conn_name, "dns_servers"); gchar *tmp; GString *dns_string = g_string_new (NULL); + const char *dns; if (!dns_servers) dns_servers = ""; for (i = 0; i < num; i++) { - ip = nm_setting_ip6_config_get_dns (s_ip6, i); + dns = nm_setting_ip_config_get_dns (s_ip6, i); - memset (buf, 0, sizeof (buf)); - inet_ntop (AF_INET6, (const void *) ip, buf, - sizeof (buf)); - if (!strstr (dns_servers, buf)) - g_string_append_printf (dns_string, "%s ", buf); + if (!strstr (dns_servers, dns)) + g_string_append_printf (dns_string, "%s ", dns); } tmp = g_strdup_printf ("%s %s", dns_servers, dns_string->str); ifnet_set_data (conn_name, "dns_servers", tmp); @@ -2686,7 +2624,7 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err } else /* DNS Searches */ - num = nm_setting_ip6_config_get_num_dns_searches (s_ip6); + num = nm_setting_ip_config_get_num_dns_searches (s_ip6); if (num > 0) { const char *ip4_domains; @@ -2698,7 +2636,7 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err const gchar *search = NULL; search = - nm_setting_ip6_config_get_dns_search (s_ip6, i); + nm_setting_ip_config_get_dns_search (s_ip6, i); if (search && !strstr (searches->str, search)) { if (searches->len > 0) g_string_append_c (searches, ' '); @@ -2716,7 +2654,7 @@ write_ip6_setting (NMConnection *connection, const char *conn_name, GError **err } static gboolean -write_pppoe_setting (const char *conn_name, NMSettingPPPOE * s_pppoe) +write_pppoe_setting (const char *conn_name, NMSettingPppoe * s_pppoe) { const gchar *value; @@ -2744,7 +2682,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, GError **error) { NMSettingConnection *s_con; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; gboolean success = FALSE; const char *type; gboolean no_8021x = FALSE; @@ -2759,7 +2697,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, type = nm_setting_connection_get_connection_type (s_con); if (!type) { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing connection type!"); goto out; } @@ -2775,7 +2713,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error)) goto out; } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { - NMSettingPPPOE *s_pppoe; + NMSettingPppoe *s_pppoe; /* Writing pppoe setting */ s_pppoe = nm_connection_get_setting_pppoe (connection); @@ -2785,7 +2723,7 @@ ifnet_update_parsers_by_connection (NMConnection *connection, wired = TRUE; no_8021x = TRUE; } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "Can't write connection type '%s'", type); goto out; } @@ -2862,7 +2800,8 @@ check_unsupported_secrets (NMSetting *setting, if (flags & NM_SETTING_PARAM_SECRET) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) + g_return_if_reached (); if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) *unsupported_secret = TRUE; } @@ -2880,39 +2819,39 @@ ifnet_can_write_connection (NMConnection *connection, GError **error) /* If the connection is not available for all users, ignore * it as this plugin only deals with System Connections */ if (nm_setting_connection_get_num_permissions (s_con)) { - g_set_error_literal (error, IFNET_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "The ifnet plugin does not support non-system-wide connections."); return FALSE; } - /* If the connection has flagged secrets, ignore - * it as this plugin does not deal with user agent service */ - nm_connection_for_each_setting_value (connection, - check_unsupported_secrets, - &has_unsupported_secrets); - if (has_unsupported_secrets) { - g_set_error_literal (error, IFNET_PLUGIN_ERROR, 0, - "The ifnet plugin only supports persistent system secrets."); - return FALSE; - } - /* Only support wired, wifi, and PPPoE */ if ( !nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME) && !nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME) && !nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { - g_set_error (error, IFNET_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "The ifnet plugin cannot write the connection '%s' (type '%s')", nm_connection_get_id (connection), nm_setting_connection_get_connection_type (s_con)); return FALSE; } + /* If the connection has flagged secrets, ignore + * it as this plugin does not deal with user agent service */ + nm_connection_for_each_setting_value (connection, + check_unsupported_secrets, + &has_unsupported_secrets); + if (has_unsupported_secrets) { + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, + "The ifnet plugin only supports persistent system secrets."); + return FALSE; + } + return TRUE; } /* get the available wired name(eth*). */ static gchar * -get_wired_name () +get_wired_name (void) { int i = 0; @@ -2929,7 +2868,7 @@ get_wired_name () /* get the available pppoe name(ppp*). */ static gchar * -get_ppp_name () +get_ppp_name (void) { int i = 0; @@ -2949,7 +2888,9 @@ static gchar * get_wireless_name (NMConnection * connection) { NMSettingWireless *s_wireless; - const GByteArray *ssid; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; gboolean hex_ssid = FALSE; gchar *result = NULL; char buf[33]; @@ -2960,12 +2901,13 @@ get_wireless_name (NMConnection * connection) return NULL; ssid = nm_setting_wireless_get_ssid (s_wireless); - if (!ssid->len || ssid->len > 32) { + ssid_data = g_bytes_get_data (ssid, &ssid_len); + if (!ssid_len || ssid_len > 32) { return NULL; } - for (i = 0; i < ssid->len; i++) { - if (!g_ascii_isprint (ssid->data[i])) { + for (i = 0; i < ssid_len; i++) { + if (!g_ascii_isprint (ssid_data[i])) { hex_ssid = TRUE; break; } @@ -2974,15 +2916,15 @@ get_wireless_name (NMConnection * connection) if (hex_ssid) { GString *str; - str = g_string_sized_new (ssid->len * 2 + 3); + str = g_string_sized_new (ssid_len * 2 + 3); g_string_append (str, "0x"); - for (i = 0; i < ssid->len; i++) - g_string_append_printf (str, "%02X", ssid->data[i]); + for (i = 0; i < ssid_len; i++) + g_string_append_printf (str, "%02X", ssid_data[i]); result = g_strdup (str->str); g_string_free (str, TRUE); } else { memset (buf, 0, sizeof (buf)); - memcpy (buf, ssid->data, ssid->len); + memcpy (buf, ssid_data, ssid_len); result = g_strdup_printf ("%s", buf); g_strstrip (result); } @@ -3031,7 +2973,7 @@ ifnet_add_new_connection (NMConnection *connection, goto out; new_type = "ppp"; } else { - g_set_error (error, ifnet_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "Can't write connection type '%s'", type); goto out; } diff --git a/src/settings/plugins/ifnet/errors.c b/src/settings/plugins/ifnet/errors.c deleted file mode 100644 index 295db18b..00000000 --- a/src/settings/plugins/ifnet/errors.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2013 Red Hat, Inc. - */ - -#include -#include "errors.h" - -GQuark -ifnet_plugin_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("ifnet-plugin-error-quark"); - - return error_quark; -} - - diff --git a/src/settings/plugins/ifnet/errors.h b/src/settings/plugins/ifnet/errors.h deleted file mode 100644 index 52517d00..00000000 --- a/src/settings/plugins/ifnet/errors.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2013 Red Hat, Inc. - */ - -#ifndef __ERRORS_H__ -#define __ERRORS_H__ - -#include - -#define IFNET_PLUGIN_ERROR (ifnet_plugin_error_quark ()) -GQuark ifnet_plugin_error_quark (void); - -#endif /* __ERRORS_H__ */ - diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index 95add14f..1cf46fbf 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -19,6 +19,8 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include #include diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index 86ab8537..adb23c43 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -19,11 +19,14 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include #include #include #include +#include #include #include #include @@ -365,23 +368,21 @@ create_ip4_block (gchar * ip) ip_mask = g_strsplit (ip, "/", 0); length = g_strv_length (ip_mask); - if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) goto error; - iblock->ip = tmp_ip4_addr; + iblock->ip = g_strdup (ip_mask[0]); prefix = ip_mask[1]; i = 0; while (i < length && g_ascii_isdigit (prefix[i])) i++; prefix[i] = '\0'; - iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32) - atoi (ip_mask - [1])); + iblock->prefix = (guint32) atoi (ip_mask[1]); } else if (strstr (ip, "netmask")) { ip_mask = g_strsplit (ip, " ", 0); length = g_strv_length (ip_mask); - if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) goto error; - iblock->ip = tmp_ip4_addr; + iblock->ip = g_strdup (ip_mask[0]); i = 0; while (i < length && !strstr (ip_mask[++i], "netmask")) ; while (i < length && ip_mask[++i][0] == '\0') ; @@ -389,39 +390,42 @@ create_ip4_block (gchar * ip) goto error; if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) goto error; - iblock->netmask = tmp_ip4_addr; + iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr); } else { g_slice_free (ip_block, iblock); if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip); return NULL; } + if (iblock->prefix == 0 || iblock->prefix > 32) { + nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip); + goto error; + } g_strfreev (ip_mask); return iblock; error: if (!is_ip6_address (ip)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip); g_strfreev (ip_mask); + g_free (iblock->ip); g_slice_free (ip_block, iblock); return NULL; } -static ip6_block * -create_ip6_block (gchar * ip) +static ip_block * +create_ip_block (gchar * ip) { - ip6_block *iblock = g_slice_new0 (ip6_block); + ip_block *iblock = g_slice_new0 (ip_block); gchar *dup_ip = g_strdup (ip); - struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); gchar *prefix = NULL; if ((prefix = strstr (dup_ip, "/")) != NULL) { *prefix = '\0'; prefix++; } - if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) { + if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip)) goto error; - } - iblock->ip = tmp_ip6_addr; + iblock->ip = dup_ip; if (prefix) { errno = 0; iblock->prefix = strtol (prefix, NULL, 10); @@ -430,30 +434,26 @@ create_ip6_block (gchar * ip) } } else iblock->prefix = 64; - g_free (dup_ip); return iblock; error: if (!is_ip4_address (ip)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip); - g_slice_free (ip6_block, iblock); - g_slice_free (struct in6_addr, tmp_ip6_addr); - + g_slice_free (ip_block, iblock); g_free (dup_ip); return NULL; } -static guint32 +static char * get_ip4_gateway (gchar * gateway) { gchar *tmp, *split; - guint32 tmp_ip4_addr; if (!gateway) - return 0; + return NULL; tmp = find_gateway_str (gateway); if (!tmp) { nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway); - return 0; + return NULL; } tmp = g_strdup (tmp); strip_string (tmp, ' '); @@ -463,43 +463,39 @@ get_ip4_gateway (gchar * gateway) if ((split = strstr (tmp, "\"")) != NULL) *split = '\0'; - if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) + if (!nm_utils_ipaddr_valid (AF_INET, tmp)) goto error; - g_free (tmp); - return tmp_ip4_addr; + return tmp; error: if (!is_ip6_address (tmp)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp); g_free (tmp); - return 0; + return NULL; } -static struct in6_addr * +static char * get_ip6_next_hop (gchar * next_hop) { gchar *tmp; - struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); if (!next_hop) - return 0; + return NULL; tmp = find_gateway_str (next_hop); if (!tmp) { nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop); - return 0; + return NULL; } tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); g_strstrip (tmp); - if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr)) + if (!nm_utils_ipaddr_valid (AF_INET6, tmp)) goto error; - g_free (tmp); - return tmp_ip6_addr; + return tmp; error: if (!is_ip4_address (tmp)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp); g_free (tmp); - g_slice_free (struct in6_addr, tmp_ip6_addr); return NULL; } @@ -511,7 +507,7 @@ convert_ip4_config_block (const char *conn_name) guint length; guint i; gchar *ip; - guint32 def_gateway = 0; + char *def_gateway = NULL; const char *routes; ip_block *start = NULL, *current = NULL, *iblock = NULL; @@ -530,8 +526,8 @@ convert_ip4_config_block (const char *conn_name) iblock = create_ip4_block (ip); if (iblock == NULL) continue; - if (!iblock->gateway && def_gateway != 0) - iblock->gateway = def_gateway; + if (!iblock->next_hop && def_gateway != NULL) + iblock->next_hop = g_strdup (def_gateway); if (start == NULL) start = current = iblock; else { @@ -540,17 +536,18 @@ convert_ip4_config_block (const char *conn_name) } } g_strfreev (ipset); + g_free (def_gateway); return start; } -ip6_block * +ip_block * convert_ip6_config_block (const char *conn_name) { gchar **ipset; guint length; guint i; gchar *ip; - ip6_block *start = NULL, *current = NULL, *iblock = NULL; + ip_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); ipset = split_addresses (ifnet_get_data (conn_name, "config")); @@ -558,7 +555,7 @@ convert_ip6_config_block (const char *conn_name) for (i = 0; i < length; i++) { ip = ipset[i]; ip = strip_string (ip, '"'); - iblock = create_ip6_block (ip); + iblock = create_ip_block (ip); if (iblock == NULL) continue; if (start == NULL) @@ -594,7 +591,7 @@ convert_ip4_routes_block (const char *conn_name) iblock = create_ip4_block (ip); if (iblock == NULL) continue; - iblock->gateway = get_ip4_gateway (ip); + iblock->next_hop = get_ip4_gateway (ip); if (start == NULL) start = current = iblock; else { @@ -606,15 +603,14 @@ convert_ip4_routes_block (const char *conn_name) return start; } -ip6_block * +ip_block * convert_ip6_routes_block (const char *conn_name) { gchar **ipset; guint length; guint i; gchar *ip, *tmp_addr; - ip6_block *start = NULL, *current = NULL, *iblock = NULL; - struct in6_addr *tmp_ip6_addr; + ip_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); ipset = split_routes (ifnet_get_data (conn_name, "routes")); @@ -628,25 +624,17 @@ convert_ip6_routes_block (const char *conn_name) if (!is_ip6_address (tmp_addr)) continue; else { - tmp_ip6_addr = g_slice_new0 (struct in6_addr); - - if (inet_pton (AF_INET6, "::", tmp_ip6_addr)) { - iblock = g_slice_new0 (ip6_block); - iblock->ip = tmp_ip6_addr; - iblock->prefix = 128; - } else { - g_slice_free (struct in6_addr, - tmp_ip6_addr); - continue; - } + iblock = g_slice_new0 (ip_block); + iblock->ip = g_strdup ("::"); + iblock->prefix = 128; } } else - iblock = create_ip6_block (ip); + iblock = create_ip_block (ip); if (iblock == NULL) continue; iblock->next_hop = get_ip6_next_hop (ip); if (iblock->next_hop == NULL) { - destroy_ip6_block (iblock); + destroy_ip_block (iblock); continue; } if (start == NULL) @@ -663,26 +651,18 @@ convert_ip6_routes_block (const char *conn_name) void destroy_ip_block (ip_block * iblock) { + g_free (iblock->ip); + g_free (iblock->next_hop); g_slice_free (ip_block, iblock); } void -destroy_ip6_block (ip6_block * iblock) -{ - g_slice_free (struct in6_addr, iblock->ip); - g_slice_free (struct in6_addr, iblock->next_hop); - - g_slice_free (ip6_block, iblock); -} - -void -set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name) +set_ip4_dns_servers (NMSettingIPConfig *s_ip4, const char *conn_name) { const char *dns_servers; gchar **server_list, *stripped; guint length, i; guint32 tmp_ip4_addr; - guint32 new_dns; dns_servers = ifnet_get_data (conn_name, "dns_servers"); if (!dns_servers) @@ -694,7 +674,7 @@ set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name) length = g_strv_length (server_list); if (length) - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); for (i = 0; i < length; i++) { g_strstrip (server_list[i]); @@ -705,15 +685,14 @@ set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name) nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); continue; } - new_dns = tmp_ip4_addr; - if (new_dns && !nm_setting_ip4_config_add_dns (s_ip4, new_dns)) + if (!nm_setting_ip_config_add_dns (s_ip4, server_list[i])) nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); } g_strfreev (server_list); } void -set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name) +set_ip6_dns_servers (NMSettingIPConfig *s_ip6, const char *conn_name) { const char *dns_servers; gchar **server_list, *stripped; @@ -731,7 +710,7 @@ set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name) length = g_strv_length (server_list); if (length) - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, TRUE, NULL); for (i = 0; i < length; i++) { g_strstrip (server_list[i]); @@ -742,8 +721,7 @@ set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name) nm_log_warn (LOGD_SETTINGS, "ignored dns: %s\n", server_list[i]); continue; } - if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_ip6_addr) - && !nm_setting_ip6_config_add_dns (s_ip6, &tmp_ip6_addr)) + if (!nm_setting_ip_config_add_dns (s_ip6, server_list[i])) nm_log_warn (LOGD_SETTINGS, "warning: duplicate DNS server %s", server_list[i]); } g_strfreev (server_list); @@ -763,30 +741,49 @@ is_managed (const char *conn_name) return TRUE; } +static char * +_has_prefix_impl (char *str, const char *prefix, gsize prefix_len) +{ + if (!g_str_has_prefix (str, prefix)) + return NULL; + str += prefix_len; + if (!g_ascii_isspace (str[0])) + return NULL; + do { + str++; + } while (g_ascii_isspace (str[0])); + return str; +} +#define _has_prefix(STR, PREFIX) _has_prefix_impl (STR, PREFIX, STRLEN (PREFIX)) + void get_dhcp_hostname_and_client_id (char **hostname, char **client_id) { const char *dhcp_client; const gchar *dhcpcd_conf = SYSCONFDIR "/dhcpcd.conf"; const gchar *dhclient_conf = SYSCONFDIR "/dhcp/dhclient.conf"; - gchar *line = NULL, *tmp = NULL, *contents = NULL; + gchar *line = NULL, *tmp = NULL, *contents = NULL, *tmp1; gchar **all_lines; guint line_num, i; + gboolean use_dhclient = FALSE; *hostname = NULL; *client_id = NULL; dhcp_client = nm_config_get_dhcp_client (nm_config_get ()); if (dhcp_client) { - if (!strcmp (dhcp_client, "dhclient")) + if (!strcmp (dhcp_client, "dhclient")) { g_file_get_contents (dhclient_conf, &contents, NULL, NULL); - else if (!strcmp (dhcp_client, "dhcpcd")) + use_dhclient = TRUE; + } else if (!strcmp (dhcp_client, "dhcpcd")) g_file_get_contents (dhcpcd_conf, &contents, NULL, NULL); } else { - if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) + if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) { g_file_get_contents (dhclient_conf, &contents, NULL, NULL); + use_dhclient = TRUE; + } else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) g_file_get_contents (dhcpcd_conf, &contents, NULL, NULL); @@ -797,42 +794,44 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) line_num = g_strv_length (all_lines); for (i = 0; i < line_num; i++) { line = all_lines[i]; - // dhcpcd.conf g_strstrip (line); - if (g_str_has_prefix (line, "hostname")) { - tmp = line + strlen ("hostname"); - g_strstrip (tmp); - if (tmp[0] != '\0') - *hostname = g_strdup (tmp); - else - nm_log_info (LOGD_SETTINGS, "dhcpcd hostname not defined, ignoring"); - } else if (g_str_has_prefix (line, "clientid")) { - tmp = line + strlen ("clientid"); - g_strstrip (tmp); - if (tmp[0] != '\0') - *client_id = g_strdup (tmp); - else - nm_log_info (LOGD_SETTINGS, "dhcpcd clientid not defined, ignoring"); - } - // dhclient.conf - else if ((tmp = strstr (line, "send host-name")) != NULL) { - tmp += strlen ("send host-name"); - g_strstrip (tmp); - strip_string (tmp, ';'); - strip_string (tmp, '"'); - if (tmp[0] != '\0') - *hostname = g_strdup (tmp); - else - nm_log_info (LOGD_SETTINGS, "dhclient hostname not defined, ignoring"); - } else if ((tmp = strstr (line, "send dhcp-client-identifier")) - != NULL) { - tmp += strlen ("send dhcp-client-identifier"); - g_strstrip (tmp); - strip_string (tmp, ';'); - if (tmp[0] != '\0') - *client_id = g_strdup (tmp); - else - nm_log_info (LOGD_SETTINGS, "dhclient clientid not defined, ignoring"); + if (line[0] == '#' || line[0] == '\0') + continue; + if (!use_dhclient) { + // dhcpcd.conf + if ((tmp = _has_prefix (line, "hostname"))) { + if (tmp[0] != '\0') { + g_free (*hostname); + *hostname = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhcpcd hostname not defined, ignoring"); + } else if ((tmp = _has_prefix (line, "clientid"))) { + if (tmp[0] != '\0') { + g_free (*client_id); + *client_id = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhcpcd clientid not defined, ignoring"); + } + } else { + // dhclient.conf + if ((tmp1 = _has_prefix (line, "send"))) { + if ((tmp = _has_prefix (tmp1, "host-name"))) { + strip_string (tmp, ';'); + strip_string (tmp, '"'); + if (tmp[0] != '\0') { + g_free (*hostname); + *hostname = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhclient hostname not defined, ignoring"); + } else if ((tmp = _has_prefix (tmp1, "dhcp-client-identifier"))) { + strip_string (tmp, ';'); + if (tmp[0] != '\0') { + g_free (*client_id); + *client_id = g_strdup (tmp); + } else + nm_log_info (LOGD_SETTINGS, "dhclient clientid not defined, ignoring"); + } + } } } g_strfreev (all_lines); diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h index cee71d57..d58e7ec6 100644 --- a/src/settings/plugins/ifnet/net_utils.h +++ b/src/settings/plugins/ifnet/net_utils.h @@ -31,19 +31,12 @@ #define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) typedef struct _ip_block { - guint32 ip; - guint32 netmask; - guint32 gateway; + char *ip; + guint32 prefix; + char *next_hop; struct _ip_block *next; } ip_block; -typedef struct _ip6_block { - struct in6_addr *ip; - long int prefix; - struct in6_addr *next_hop; - struct _ip6_block *next; -} ip6_block; - gchar *read_hostname (const char *path); gboolean write_hostname (const char *path, const char *hostname); gboolean is_static_ip4 (const char *conn_name); @@ -55,14 +48,13 @@ gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const c gboolean reload_parsers (void); ip_block *convert_ip4_config_block (const char *conn_name); -ip6_block *convert_ip6_config_block (const char *conn_name); +ip_block *convert_ip6_config_block (const char *conn_name); ip_block *convert_ip4_routes_block (const char *conn_name); -ip6_block *convert_ip6_routes_block (const char *conn_name); +ip_block *convert_ip6_routes_block (const char *conn_name); void destroy_ip_block (ip_block * iblock); -void destroy_ip6_block (ip6_block * iblock); -void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, const char *conn_name); -void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, const char *conn_name); +void set_ip4_dns_servers (NMSettingIPConfig * s_ip4, const char *conn_name); +void set_ip6_dns_servers (NMSettingIPConfig * s_ip6, const char *conn_name); gchar *strip_string (gchar *str, gchar t); gboolean is_managed (const char *conn_name); diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.c b/src/settings/plugins/ifnet/nm-ifnet-connection.c index 478d6e32..c84ad5ed 100644 --- a/src/settings/plugins/ifnet/nm-ifnet-connection.c +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.c @@ -19,15 +19,16 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include -#include +#include #include #include #include #include #include -#include #include "nm-ifnet-connection.h" #include "connection_parser.h" #include "net_parser.h" diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.h b/src/settings/plugins/ifnet/nm-ifnet-connection.h index 1cb67c34..baa4c07e 100644 --- a/src/settings/plugins/ifnet/nm-ifnet-connection.h +++ b/src/settings/plugins/ifnet/nm-ifnet-connection.h @@ -19,8 +19,8 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ -#ifndef NM_IFNET_CONNECTION_H -#define NM_IFNET_CONNECTION_H +#ifndef __NETWORKMANAGER_IFNET_CONNECTION_H__ +#define __NETWORKMANAGER_IFNET_CONNECTION_H__ #include #include "net_parser.h" diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c index ab07b8d6..3eb1ed52 100644 --- a/src/settings/plugins/ifnet/plugin.c +++ b/src/settings/plugins/ifnet/plugin.c @@ -20,6 +20,8 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include @@ -29,7 +31,7 @@ #include #include -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-system-config-interface.h" #include "nm-logging.h" #include "nm-ifnet-connection.h" diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am index f66a6a3d..66409a54 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.am +++ b/src/settings/plugins/ifnet/tests/Makefile.am @@ -4,22 +4,17 @@ if ENABLE_TESTS AM_CPPFLAGS= \ -I$(srcdir)/../ \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/src/platform \ -DG_LOG_DOMAIN=\""NetworkManager-ifnet"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(CHECK_CFLAGS) \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(CODE_COVERAGE_CFLAGS) \ -DTEST_WPA_SUPPLICANT_CONF='"$(srcdir)/wpa_supplicant.conf"' \ -DSYSCONFDIR=\"nonexistent\" @@ -30,8 +25,7 @@ check_ifnet_SOURCES = \ ../connection_parser.c \ ../net_parser.c \ ../net_utils.c \ - ../wpa_parser.c \ - ../errors.c + ../wpa_parser.c check_ifnet_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) @@ -41,6 +35,8 @@ check_ifnet_LDADD = $(top_builddir)/src/libNetworkManager.la check-local: check_ifnet $(abs_builddir)/check_ifnet $(abs_srcdir) $(abs_builddir) +endif + EXTRA_DIST = \ hostname \ net \ @@ -48,5 +44,3 @@ EXTRA_DIST = \ nm-system-settings.conf \ wpa_supplicant.conf \ test_ca_cert.pem - -endif diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in index cd604237..8293c869 100644 --- a/src/settings/plugins/ifnet/tests/Makefile.in +++ b/src/settings/plugins/ifnet/tests/Makefile.in @@ -104,11 +104,11 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__check_ifnet_SOURCES_DIST = test_all.c ../connection_parser.c \ - ../net_parser.c ../net_utils.c ../wpa_parser.c ../errors.c + ../net_parser.c ../net_utils.c ../wpa_parser.c @ENABLE_TESTS_TRUE@am_check_ifnet_OBJECTS = test_all.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ connection_parser.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ net_parser.$(OBJEXT) net_utils.$(OBJEXT) \ -@ENABLE_TESTS_TRUE@ wpa_parser.$(OBJEXT) errors.$(OBJEXT) +@ENABLE_TESTS_TRUE@ wpa_parser.$(OBJEXT) check_ifnet_OBJECTS = $(am_check_ifnet_OBJECTS) @ENABLE_TESTS_TRUE@check_ifnet_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la @@ -189,6 +189,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -312,6 +314,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -331,6 +334,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -357,7 +361,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -438,22 +442,17 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/config \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/logging \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/platform \ @ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-ifnet"\" \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ $(CHECK_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(POLKIT_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_CFLAGS) \ @ENABLE_TESTS_TRUE@ -DTEST_WPA_SUPPLICANT_CONF='"$(srcdir)/wpa_supplicant.conf"' \ @ENABLE_TESTS_TRUE@ -DSYSCONFDIR=\"nonexistent\" @@ -463,20 +462,19 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ ../connection_parser.c \ @ENABLE_TESTS_TRUE@ ../net_parser.c \ @ENABLE_TESTS_TRUE@ ../net_utils.c \ -@ENABLE_TESTS_TRUE@ ../wpa_parser.c \ -@ENABLE_TESTS_TRUE@ ../errors.c +@ENABLE_TESTS_TRUE@ ../wpa_parser.c @ENABLE_TESTS_TRUE@check_ifnet_LDFLAGS = \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_LDFLAGS) @ENABLE_TESTS_TRUE@check_ifnet_LDADD = $(top_builddir)/src/libNetworkManager.la -@ENABLE_TESTS_TRUE@EXTRA_DIST = \ -@ENABLE_TESTS_TRUE@ hostname \ -@ENABLE_TESTS_TRUE@ net \ -@ENABLE_TESTS_TRUE@ net.all \ -@ENABLE_TESTS_TRUE@ nm-system-settings.conf \ -@ENABLE_TESTS_TRUE@ wpa_supplicant.conf \ -@ENABLE_TESTS_TRUE@ test_ca_cert.pem +EXTRA_DIST = \ + hostname \ + net \ + net.all \ + nm-system-settings.conf \ + wpa_supplicant.conf \ + test_ca_cert.pem all: all-am @@ -533,7 +531,6 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection_parser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_all.Po@am__quote@ @@ -616,20 +613,6 @@ wpa_parser.obj: ../wpa_parser.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wpa_parser.obj `if test -f '../wpa_parser.c'; then $(CYGPATH_W) '../wpa_parser.c'; else $(CYGPATH_W) '$(srcdir)/../wpa_parser.c'; fi` -errors.o: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.o -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c - -errors.obj: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.obj -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` - mostlyclean-libtool: -rm -f *.lo diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index c320ed5f..9c399128 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -20,6 +20,8 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include #include @@ -55,7 +57,7 @@ nm_config_get_dhcp_client (NMConfig *config) } static void -test_getdata () +test_getdata (void) { ASSERT (ifnet_get_data ("eth1", "config") && strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0, @@ -103,7 +105,7 @@ test_write_hostname (const char *temp_path) } static void -test_is_static () +test_is_static (void) { ASSERT (is_static_ip4 ("eth1") == FALSE, "is static", "a dhcp interface is recognized as static"); @@ -114,7 +116,7 @@ test_is_static () } static void -test_has_default_route () +test_has_default_route (void) { ASSERT (has_default_ip4_route ("eth0"), "has default route", "eth0 should have a default ipv4 route"); @@ -126,7 +128,7 @@ test_has_default_route () } static void -test_has_ip6_address () +test_has_ip6_address (void) { ASSERT (has_ip6_address ("eth2"), "has ip6 address", "eth2 should have a ipv6 address"); @@ -136,7 +138,7 @@ test_has_ip6_address () } static void -test_is_ip4_address () +test_is_ip4_address (void) { gchar *address1 = "192.168.4.232/24"; gchar *address2 = "192.168.100.{1..254}/24"; @@ -151,7 +153,7 @@ test_is_ip4_address () } static void -test_is_ip6_address () +test_is_ip6_address (void) { gchar *address1 = "4321:0:1:2:3:4:567:89ac/24"; @@ -160,43 +162,30 @@ test_is_ip6_address () } static void -check_ip_block (ip_block * iblock, gchar * ip, gchar * netmask, gchar * gateway) +check_ip_block (ip_block * iblock, gchar * ip, guint32 prefix, gchar * gateway) { - char *str; - guint32 tmp_ip4_addr; - - str = malloc (INET_ADDRSTRLEN); - tmp_ip4_addr = iblock->ip; - inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); - ASSERT (strcmp (ip, str) == 0, "check ip", - "ip expected:%s, find:%s", ip, str); - tmp_ip4_addr = iblock->netmask; - inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); - ASSERT (strcmp (netmask, str) == 0, "check netmask", - "netmask expected:%s, find:%s", netmask, str); - tmp_ip4_addr = iblock->gateway; - inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); - ASSERT (strcmp (gateway, str) == 0, "check gateway", - "gateway expected:%s, find:%s", gateway, str); - free (str); + ASSERT (strcmp (ip, iblock->ip) == 0, "check ip", + "ip expected:%s, find:%s", ip, iblock->ip); + ASSERT (prefix == iblock->prefix, "check netmask", + "prefix expected:%d, find:%d", prefix, iblock->prefix); + ASSERT (g_strcmp0 (gateway, iblock->next_hop) == 0, "check gateway", + "gateway expected:%s, find:%s", gateway, iblock->next_hop); } static void -test_convert_ipv4_config_block () +test_convert_ipv4_config_block (void) { ip_block *iblock = convert_ip4_config_block ("eth0"); ip_block *tmp = iblock; ASSERT (iblock != NULL, "convert ipv4 block", "block eth0 should not be NULL"); - check_ip_block (iblock, "202.117.16.121", "255.255.255.0", - "202.117.16.1"); + check_ip_block (iblock, "202.117.16.121", 24, "202.117.16.1"); iblock = iblock->next; destroy_ip_block (tmp); ASSERT (iblock != NULL, "convert ipv4 block", "block eth0 should have a second IP address"); - check_ip_block (iblock, "192.168.4.121", "255.255.255.0", - "202.117.16.1"); + check_ip_block (iblock, "192.168.4.121", 24, "202.117.16.1"); destroy_ip_block (iblock); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, @@ -206,7 +195,7 @@ test_convert_ipv4_config_block () ASSERT (iblock != NULL && iblock->next == NULL, "convert error IPv4 address", "should only get one address"); - check_ip_block (iblock, "192.168.4.121", "255.255.255.0", "0.0.0.0"); + check_ip_block (iblock, "192.168.4.121", 24, NULL); destroy_ip_block (iblock); g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, @@ -214,17 +203,16 @@ test_convert_ipv4_config_block () iblock = convert_ip4_config_block ("eth3"); ASSERT (iblock == NULL, "convert config_block", "convert error configuration"); - destroy_ip_block (iblock); } static void -test_convert_ipv4_routes_block () +test_convert_ipv4_routes_block (void) { ip_block *iblock = convert_ip4_routes_block ("eth0"); ip_block *tmp = iblock; ASSERT (iblock != NULL, "convert ip4 routes", "should get one route"); - check_ip_block (iblock, "192.168.4.0", "255.255.255.0", "192.168.4.1"); + check_ip_block (iblock, "192.168.4.0", 24, "192.168.4.1"); iblock = iblock->next; destroy_ip_block (tmp); ASSERT (iblock == NULL, "convert ip4 routes", @@ -234,7 +222,7 @@ test_convert_ipv4_routes_block () tmp = iblock; ASSERT (iblock != NULL, "convert ip4 routes", "should get one route"); - check_ip_block (iblock, "10.0.0.0", "255.0.0.0", "192.168.0.1"); + check_ip_block (iblock, "10.0.0.0", 8, "192.168.0.1"); iblock = iblock->next; destroy_ip_block (tmp); ASSERT (iblock == NULL, "convert ip4 routes", @@ -242,7 +230,7 @@ test_convert_ipv4_routes_block () } static void -test_wpa_parser () +test_wpa_parser (void) { const char *value; @@ -261,7 +249,7 @@ test_wpa_parser () } static void -test_strip_string () +test_strip_string (void) { gchar *str = "( \"default via 202.117.16.1\" )"; gchar *result = g_strdup (str); @@ -277,7 +265,7 @@ test_strip_string () } static void -test_is_unmanaged () +test_is_unmanaged (void) { ASSERT (is_managed ("eth0"), "test_is_unmanaged", "eth0 should be managed"); @@ -286,7 +274,7 @@ test_is_unmanaged () } static void -test_new_connection () +test_new_connection (void) { GError *error = NULL; NMConnection *connection; @@ -409,7 +397,7 @@ test_add_connection (const char *basepath) } static void -test_delete_connection () +test_delete_connection (void) { GError *error = NULL; NMConnection *connection; @@ -438,7 +426,7 @@ test_delete_connection () } static void -test_missing_config () +test_missing_config (void) { GError *error = NULL; NMConnection *connection; diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c index 748eb351..3f912da8 100644 --- a/src/settings/plugins/ifnet/wpa_parser.c +++ b/src/settings/plugins/ifnet/wpa_parser.c @@ -19,6 +19,8 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ +#include "config.h" + #include #include #include @@ -166,7 +168,7 @@ add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key) /* Reading wep security information from /etc/conf.d/net. * This should not be used in future, use wpa_supplicant instead. */ static void -add_keys_from_net () +add_keys_from_net (void) { GList *names = ifnet_get_connection_names (); GList *iter = names; diff --git a/src/settings/plugins/ifupdown/Makefile.am b/src/settings/plugins/ifupdown/Makefile.am index fd98f8fe..0ca543e3 100644 --- a/src/settings/plugins/ifupdown/Makefile.am +++ b/src/settings/plugins/ifupdown/Makefile.am @@ -4,19 +4,14 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/logging \ - -I$(top_srcdir)/src/config \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifupdown"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(GUDEV_CFLAGS) \ -DSYSCONFDIR=\"$(sysconfdir)\" @@ -28,10 +23,6 @@ libifupdown_io_la_SOURCES = \ parser.c \ parser.h -libifupdown_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) - pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la libnm_settings_plugin_ifupdown_la_SOURCES = \ @@ -41,9 +32,5 @@ libnm_settings_plugin_ifupdown_la_SOURCES = \ plugin.h libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifupdown_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - libifupdown-io.la \ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) +libnm_settings_plugin_ifupdown_la_LIBADD = libifupdown-io.la diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in index 50d4ca08..44596e48 100644 --- a/src/settings/plugins/ifupdown/Makefile.in +++ b/src/settings/plugins/ifupdown/Makefile.in @@ -130,18 +130,14 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) -am__DEPENDENCIES_1 = -libifupdown_io_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) +libifupdown_io_la_LIBADD = am_libifupdown_io_la_OBJECTS = interface_parser.lo parser.lo libifupdown_io_la_OBJECTS = $(am_libifupdown_io_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libnm_settings_plugin_ifupdown_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la libifupdown-io.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +libnm_settings_plugin_ifupdown_la_DEPENDENCIES = libifupdown-io.la am_libnm_settings_plugin_ifupdown_la_OBJECTS = \ nm-ifupdown-connection.lo plugin.lo libnm_settings_plugin_ifupdown_la_OBJECTS = \ @@ -264,6 +260,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -387,6 +385,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -406,6 +405,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -432,7 +432,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -514,19 +514,14 @@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/logging \ - -I$(top_srcdir)/src/config \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-glib \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-ifupdown"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(GUDEV_CFLAGS) \ -DSYSCONFDIR=\"$(sysconfdir)\" @@ -537,10 +532,6 @@ libifupdown_io_la_SOURCES = \ parser.c \ parser.h -libifupdown_io_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(GLIB_LIBS) - pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la libnm_settings_plugin_ifupdown_la_SOURCES = \ nm-ifupdown-connection.c \ @@ -549,12 +540,7 @@ libnm_settings_plugin_ifupdown_la_SOURCES = \ plugin.h libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version -libnm_settings_plugin_ifupdown_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - libifupdown-io.la \ - $(GLIB_LIBS) \ - $(GUDEV_LIBS) - +libnm_settings_plugin_ifupdown_la_LIBADD = libifupdown-io.la all: all-recursive .SUFFIXES: diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c index ee233c93..32d27c57 100644 --- a/src/settings/plugins/ifupdown/interface_parser.c +++ b/src/settings/plugins/ifupdown/interface_parser.c @@ -21,6 +21,7 @@ */ #include "config.h" + #include "interface_parser.h" #include #include diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.c b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c index 4e13a2b8..c6073bd7 100644 --- a/src/settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -21,14 +21,15 @@ * (C) Copyright 2007,2008 Canonical Ltd. */ +#include "config.h" + #include #include -#include +#include #include #include #include #include -#include #include #include "nm-ifupdown-connection.h" #include "parser.h" @@ -161,9 +162,8 @@ nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connectio /* Properties */ g_object_class_install_property (object_class, PROP_IFBLOCK, - g_param_spec_pointer (NM_IFUPDOWN_CONNECTION_IFBLOCK, - "ifblock", - "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_pointer (NM_IFUPDOWN_CONNECTION_IFBLOCK, "", "", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h index 447af78a..be2ebc0a 100644 --- a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h +++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h @@ -21,8 +21,8 @@ * (C) Copyright 2008 Canonical Ltd. */ -#ifndef NM_IFUPDOWN_CONNECTION_H -#define NM_IFUPDOWN_CONNECTION_H +#ifndef __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ +#define __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ #include #include "interface_parser.h" @@ -52,4 +52,4 @@ NMIfupdownConnection *nm_ifupdown_connection_new (if_block *block); G_END_DECLS -#endif /* NM_IFUPDOWN_CONNECTION_H */ +#endif /* __NETWORKMANAGER_IFUPDOWN_CONNECTION_H__ */ diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c index 91ed3e21..15081a4c 100644 --- a/src/settings/plugins/ifupdown/parser.c +++ b/src/settings/plugins/ifupdown/parser.c @@ -21,24 +21,18 @@ * (C) Copyright 2008 Canonical Ltd. */ +#include "config.h" + #include #include #include #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include "nm-core-internal.h" +#include "nm-system-config-interface.h" +#include "nm-logging.h" + #include "parser.h" #include "plugin.h" @@ -417,19 +411,8 @@ update_wired_setting_from_if_block(NMConnection *connection, nm_connection_add_setting(connection, NM_SETTING(s_wired)); } -static GQuark -eni_plugin_error_quark() { - static GQuark error_quark = 0; - - if(!error_quark) { - error_quark = g_quark_from_static_string ("eni-plugin-error-quark"); - } - - return error_quark; -} - static void -ifupdown_ip4_add_dns (NMSettingIP4Config *s_ip4, const char *dns) +ifupdown_ip4_add_dns (NMSettingIPConfig *s_ip4, const char *dns) { guint32 addr; char **list, **iter; @@ -447,7 +430,7 @@ ifupdown_ip4_add_dns (NMSettingIP4Config *s_ip4, const char *dns) continue; } - if (!nm_setting_ip4_config_add_dns (s_ip4, addr)) + if (!nm_setting_ip_config_add_dns (s_ip4, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); @@ -459,15 +442,15 @@ update_ip4_setting_from_if_block(NMConnection *connection, GError **error) { - NMSettingIP4Config *s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new()); + NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new()); const char *type = ifparser_getkey(block, "inet"); gboolean is_static = type && !strcmp("static", type); if (!is_static) { - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); } else { - guint32 tmp_addr, tmp_mask, tmp_gw; - NMIP4Address *addr; + guint32 tmp_mask; + NMIPAddress *addr; const char *address_v; const char *netmask_v; const char *gateway_v; @@ -479,10 +462,9 @@ update_ip4_setting_from_if_block(NMConnection *connection, /* Address */ address_v = ifparser_getkey (block, "address"); - if (!address_v || !inet_pton (AF_INET, address_v, &tmp_addr)) { - g_set_error (error, eni_plugin_error_quark (), 0, - "Missing IPv4 address '%s'", - address_v ? address_v : "(none)"); + if (!address_v) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IPv4 address"); goto error; } @@ -491,13 +473,8 @@ update_ip4_setting_from_if_block(NMConnection *connection, if (netmask_v) { if (strlen (netmask_v) < 7) { netmask_int = atoi (netmask_v); - if (netmask_int > 32) { - g_set_error (error, eni_plugin_error_quark (), 0, - "Invalid IPv4 netmask '%s'", netmask_v); - goto error; - } } else if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) { - g_set_error (error, eni_plugin_error_quark (), 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv4 netmask '%s'", netmask_v); goto error; } else { @@ -505,29 +482,30 @@ update_ip4_setting_from_if_block(NMConnection *connection, } } - /* gateway */ - gateway_v = ifparser_getkey (block, "gateway"); - if (!gateway_v) - gateway_v = address_v; /* dcbw: whaaa?? */ - if (!inet_pton (AF_INET, gateway_v, &tmp_gw)) { - g_set_error (error, eni_plugin_error_quark (), 0, - "Invalid IPv4 gateway '%s'", gateway_v); - goto error; - } - /* Add the new address to the setting */ - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, tmp_addr); - nm_ip4_address_set_prefix (addr, netmask_int); - nm_ip4_address_set_gateway (addr, tmp_gw); + addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error); + if (!addr) + goto error; - if (nm_setting_ip4_config_add_address (s_ip4, addr)) { + if (nm_setting_ip_config_add_address (s_ip4, addr)) { nm_log_info (LOGD_SETTINGS, "addresses count: %d", - nm_setting_ip4_config_get_num_addresses (s_ip4)); + nm_setting_ip_config_get_num_addresses (s_ip4)); } else { nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP4 address"); } - nm_ip4_address_unref (addr); + nm_ip_address_unref (addr); + + /* gateway */ + gateway_v = ifparser_getkey (block, "gateway"); + if (gateway_v) { + if (!nm_utils_ipaddr_valid (AF_INET, gateway_v)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IPv4 gateway '%s'", gateway_v); + goto error; + } + if (!nm_setting_ip_config_get_gateway (s_ip4)) + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); + } nameserver_v = ifparser_getkey (block, "dns-nameserver"); ifupdown_ip4_add_dns (s_ip4, nameserver_v); @@ -535,7 +513,7 @@ update_ip4_setting_from_if_block(NMConnection *connection, nameservers_v = ifparser_getkey (block, "dns-nameservers"); ifupdown_ip4_add_dns (s_ip4, nameservers_v); - if (!nm_setting_ip4_config_get_num_dns (s_ip4)) + if (!nm_setting_ip_config_get_num_dns (s_ip4)) nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ @@ -546,13 +524,13 @@ update_ip4_setting_from_if_block(NMConnection *connection, g_strstrip (*iter); if (g_ascii_isspace (*iter[0])) continue; - if (!nm_setting_ip4_config_add_dns_search (s_ip4, *iter)) + if (!nm_setting_ip_config_add_dns_search (s_ip4, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); } - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); } nm_connection_add_setting (connection, NM_SETTING (s_ip4)); @@ -564,7 +542,7 @@ error: } static void -ifupdown_ip6_add_dns (NMSettingIP6Config *s_ip6, const char *dns) +ifupdown_ip6_add_dns (NMSettingIPConfig *s_ip6, const char *dns) { struct in6_addr addr; char **list, **iter; @@ -582,7 +560,7 @@ ifupdown_ip6_add_dns (NMSettingIP6Config *s_ip6, const char *dns) continue; } - if (!nm_setting_ip6_config_add_dns (s_ip6, &addr)) + if (!nm_setting_ip_config_add_dns (s_ip6, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); @@ -593,16 +571,15 @@ update_ip6_setting_from_if_block(NMConnection *connection, if_block *block, GError **error) { - NMSettingIP6Config *s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new()); + NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new()); const char *type = ifparser_getkey(block, "inet6"); gboolean is_static = type && (!strcmp("static", type) || !strcmp("v4tunnel", type)); if (!is_static) { - g_object_set(s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); } else { - struct in6_addr tmp_addr, tmp_gw; - NMIP6Address *addr; + NMIPAddress *addr; const char *address_v; const char *prefix_v; const char *gateway_v; @@ -614,10 +591,9 @@ update_ip6_setting_from_if_block(NMConnection *connection, /* Address */ address_v = ifparser_getkey(block, "address"); - if (!address_v || !inet_pton (AF_INET6, address_v, &tmp_addr)) { - g_set_error (error, eni_plugin_error_quark (), 0, - "Missing IPv6 address '%s'", - address_v ? address_v : "(none)"); + if (!address_v) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IPv6 address"); goto error; } @@ -626,29 +602,30 @@ update_ip6_setting_from_if_block(NMConnection *connection, if (prefix_v) prefix_int = g_ascii_strtoll (prefix_v, NULL, 10); - /* Gateway */ - gateway_v = ifparser_getkey (block, "gateway"); - if (!gateway_v) - gateway_v = address_v; /* dcbw: whaaa?? */ - if (!inet_pton (AF_INET6, gateway_v, &tmp_gw)) { - g_set_error (error, eni_plugin_error_quark (), 0, - "Invalid IPv6 gateway '%s'", gateway_v); - goto error; - } - /* Add the new address to the setting */ - addr = nm_ip6_address_new (); - nm_ip6_address_set_address (addr, &tmp_addr); - nm_ip6_address_set_prefix (addr, prefix_int); - nm_ip6_address_set_gateway (addr, &tmp_gw); + addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error); + if (!addr) + goto error; - if (nm_setting_ip6_config_add_address (s_ip6, addr)) { + if (nm_setting_ip_config_add_address (s_ip6, addr)) { nm_log_info (LOGD_SETTINGS, "addresses count: %d", - nm_setting_ip6_config_get_num_addresses (s_ip6)); + nm_setting_ip_config_get_num_addresses (s_ip6)); } else { nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP6 address"); } - nm_ip6_address_unref (addr); + nm_ip_address_unref (addr); + + /* gateway */ + gateway_v = ifparser_getkey (block, "gateway"); + if (gateway_v) { + if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IPv6 gateway '%s'", gateway_v); + goto error; + } + if (!nm_setting_ip_config_get_gateway (s_ip6)) + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); + } nameserver_v = ifparser_getkey(block, "dns-nameserver"); ifupdown_ip6_add_dns (s_ip6, nameserver_v); @@ -656,7 +633,7 @@ update_ip6_setting_from_if_block(NMConnection *connection, nameservers_v = ifparser_getkey(block, "dns-nameservers"); ifupdown_ip6_add_dns (s_ip6, nameservers_v); - if (!nm_setting_ip6_config_get_num_dns (s_ip6)) + if (!nm_setting_ip_config_get_num_dns (s_ip6)) nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ @@ -667,14 +644,14 @@ update_ip6_setting_from_if_block(NMConnection *connection, g_strstrip (*iter); if (isblank (*iter[0])) continue; - if (!nm_setting_ip6_config_add_dns_search (s_ip6, *iter)) + if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); } g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); } @@ -709,7 +686,7 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); uuid_base = idstr; - uuid = nm_utils_uuid_generate_from_string (uuid_base); + uuid = nm_utils_uuid_generate_from_string (uuid_base, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_INTERFACE_NAME, block->name, diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c index dcae211c..1b5642af 100644 --- a/src/settings/plugins/ifupdown/plugin.c +++ b/src/settings/plugins/ifupdown/plugin.c @@ -22,11 +22,11 @@ * (C) Copyright 2009 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include -#include -#include #include #include @@ -36,13 +36,14 @@ #include "interface_parser.h" -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-system-config-interface.h" #include "nm-setting-ip4-config.h" #include "nm-setting-wireless.h" #include "nm-setting-wired.h" #include "nm-setting-ppp.h" #include "nm-utils.h" +#include "nm-core-internal.h" #include "nm-ifupdown-connection.h" #include "plugin.h" @@ -186,7 +187,6 @@ bind_device_to_connection (SCPluginIfupdown *self, GUdevDevice *device, NMIfupdownConnection *exported) { - GByteArray *mac_address; NMSettingWired *s_wired; NMSettingWireless *s_wifi; const char *iface, *address; @@ -203,8 +203,7 @@ bind_device_to_connection (SCPluginIfupdown *self, return; } - mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER); - if (!mac_address) { + if (!nm_utils_hwaddr_valid (address, ETH_ALEN)) { nm_log_warn (LOGD_SETTINGS, "failed to parse MAC address '%s' for %s", address, iface); return; @@ -214,12 +213,11 @@ bind_device_to_connection (SCPluginIfupdown *self, s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (exported)); if (s_wired) { nm_log_info (LOGD_SETTINGS, "locking wired connection setting"); - g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, address, NULL); } else if (s_wifi) { nm_log_info (LOGD_SETTINGS, "locking wireless connection setting"); - g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL); + g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, address, NULL); } - g_byte_array_free (mac_address, TRUE); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), NULL, NULL); } @@ -507,9 +505,7 @@ static GSList* SCPluginIfupdown_get_connections (NMSystemConfigInterface *config) { SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config); - GSList *connections = NULL; - GHashTableIter iter; - gpointer value; + GSList *connections; nm_log_info (LOGD_SETTINGS, "(%d) ... get_connections.", GPOINTER_TO_UINT(config)); @@ -518,9 +514,7 @@ SCPluginIfupdown_get_connections (NMSystemConfigInterface *config) return NULL; } - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &value)) - connections = g_slist_prepend (connections, value); + connections = _nm_utils_hash_values_to_slist (priv->connections); nm_log_info (LOGD_SETTINGS, "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections)); return connections; diff --git a/src/settings/plugins/ifupdown/plugin.h b/src/settings/plugins/ifupdown/plugin.h index ed7732b8..943b8b9f 100644 --- a/src/settings/plugins/ifupdown/plugin.h +++ b/src/settings/plugins/ifupdown/plugin.h @@ -48,6 +48,4 @@ struct _SCPluginIfupdownClass { GType sc_plugin_ifupdown_get_type (void); -GQuark ifupdown_plugin_error_quark (void); - #endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am index 160b3327..24cdd955 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.am +++ b/src/settings/plugins/ifupdown/tests/Makefile.am @@ -2,19 +2,15 @@ if ENABLE_TESTS AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(srcdir)/../ \ -DG_LOG_DOMAIN=\""NetworkManager-ifupdown"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -DTEST_ENI_DIR=\"$(abs_srcdir)\" noinst_PROGRAMS = test-ifupdown @@ -25,17 +21,14 @@ test_ifupdown_SOURCES = \ ../parser.c test_ifupdown_LDADD = \ - $(top_builddir)/src/libNetworkManager.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) + $(top_builddir)/src/libNetworkManager.la TESTS = test-ifupdown +endif + EXTRA_DIST = \ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ test13 test14 test15 test16 test17-wired-static-verify-ip4 \ test18-wired-static-verify-ip6 test19-wired-static-verify-ip4-plen \ test20-source-stanza test20-source-stanza.eth0 test20-source-stanza.eth1 - -endif diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in index 86afefe6..6dedec00 100644 --- a/src/settings/plugins/ifupdown/tests/Makefile.in +++ b/src/settings/plugins/ifupdown/tests/Makefile.in @@ -109,12 +109,8 @@ am__test_ifupdown_SOURCES_DIST = test-ifupdown.c ../interface_parser.c \ @ENABLE_TESTS_TRUE@am_test_ifupdown_OBJECTS = test-ifupdown.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ interface_parser.$(OBJEXT) parser.$(OBJEXT) test_ifupdown_OBJECTS = $(am_test_ifupdown_OBJECTS) -am__DEPENDENCIES_1 = @ENABLE_TESTS_TRUE@test_ifupdown_DEPENDENCIES = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -211,6 +207,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -334,6 +332,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -353,6 +352,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -379,7 +379,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -460,19 +460,15 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/logging \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ @ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ @ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-ifupdown"\" \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(POLKIT_CFLAGS) \ @ENABLE_TESTS_TRUE@ -DTEST_ENI_DIR=\"$(abs_srcdir)\" @ENABLE_TESTS_TRUE@test_ifupdown_SOURCES = \ @@ -481,16 +477,13 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ ../parser.c @ENABLE_TESTS_TRUE@test_ifupdown_LDADD = \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) - -@ENABLE_TESTS_TRUE@EXTRA_DIST = \ -@ENABLE_TESTS_TRUE@ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ -@ENABLE_TESTS_TRUE@ test13 test14 test15 test16 test17-wired-static-verify-ip4 \ -@ENABLE_TESTS_TRUE@ test18-wired-static-verify-ip6 test19-wired-static-verify-ip4-plen \ -@ENABLE_TESTS_TRUE@ test20-source-stanza test20-source-stanza.eth0 test20-source-stanza.eth1 +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la + +EXTRA_DIST = \ + test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \ + test13 test14 test15 test16 test17-wired-static-verify-ip4 \ + test18-wired-static-verify-ip6 test19-wired-static-verify-ip4-plen \ + test20-source-stanza test20-source-stanza.eth0 test20-source-stanza.eth1 all: all-am diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index 83864287..1c100ac2 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -18,11 +18,12 @@ * */ +#include "config.h" + #include #include -#include - +#include "nm-core-internal.h" #include "nm-logging.h" #include "interface_parser.h" #include "parser.h" @@ -460,20 +461,15 @@ test17_read_static_ipv4 (const char *path) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSettingWired *s_wired; char *unmanaged = NULL; GError *error = NULL; const char* tmp; - const char *expected_address = "10.0.0.3"; const char *expected_id = "Ifupdown (eth0)"; - const char *expected_dns1 = "10.0.0.1"; - const char *expected_dns2 = "10.0.0.2"; const char *expected_search1 = "example.com"; const char *expected_search2 = "foo.example.com"; - guint32 expected_prefix = 8; - NMIP4Address *ip4_addr; - guint32 addr; + NMIPAddress *ip4_addr; #define TEST17_NAME "wired-static-verify-ip4" if_block *block = NULL; @@ -481,7 +477,7 @@ test17_read_static_ipv4 (const char *path) init_ifparser_with_file (path, file); block = ifparser_getfirst (); - connection = nm_connection_new(); + connection = nm_simple_connection_new(); ifupdown_update_connection_from_if_block(connection, block, &error); ASSERT (connection != NULL, @@ -524,10 +520,6 @@ test17_read_static_ipv4 (const char *path) /* ===== IPv4 SETTING ===== */ - ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0, - TEST17_NAME, "failed to verify %s: couldn't convert IP address #1", - file); - s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, TEST17_NAME, "failed to verify %s: missing %s setting", @@ -535,101 +527,81 @@ test17_read_static_ipv4 (const char *path) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* IP addresses */ - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 1, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); - - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - TEST17_NAME, "failed to verify %s: missing IP4 address #1", - file); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, - TEST17_NAME, "failed to verify %s: unexpected IP4 address prefix", - file); + NM_SETTING_IP_CONFIG_ADDRESSES); - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - TEST17_NAME, "failed to verify %s: unexpected IP4 address: %s", - file, addr); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip4) == 2, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, - TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #1", - file, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, + ASSERT (!strcmp (nm_setting_ip_config_get_dns (s_ip4, 0), "10.0.0.1"), TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #1", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, - TEST17_NAME, "failed to verify %s: couldn't convert DNS IP address #2", - file, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, + ASSERT (!strcmp (nm_setting_ip_config_get_dns (s_ip4, 1), "10.0.0.2"), TEST17_NAME, "failed to verify %s: unexpected %s / %s key value #2", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 1, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS search domains */ - ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns_searches (s_ip4) == 2, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0); + tmp = nm_setting_ip_config_get_dns_search (s_ip4, 0); ASSERT (tmp != NULL, TEST17_NAME, "failed to verify %s: missing %s / %s key", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, expected_search1) == 0, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1); + tmp = nm_setting_ip_config_get_dns_search (s_ip4, 1); ASSERT (tmp != NULL, TEST17_NAME, "failed to verify %s: missing %s / %s key", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, expected_search2) == 0, TEST17_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); g_object_unref (connection); } @@ -639,27 +611,22 @@ test18_read_static_ipv6 (const char *path) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; NMSettingWired *s_wired; char *unmanaged = NULL; GError *error = NULL; const char* tmp; - const char *expected_address = "fc00::1"; const char *expected_id = "Ifupdown (myip6tunnel)"; - const char *expected_dns1 = "fc00::2"; - const char *expected_dns2 = "fc00::3"; const char *expected_search1 = "example.com"; const char *expected_search2 = "foo.example.com"; - guint32 expected_prefix = 64; - NMIP6Address *ip6_addr; - struct in6_addr addr; + NMIPAddress *ip6_addr; if_block *block = NULL; #define TEST18_NAME "wired-static-verify-ip6" const char* file = "test18-" TEST18_NAME; init_ifparser_with_file (path, file); block = ifparser_getfirst (); - connection = nm_connection_new(); + connection = nm_simple_connection_new(); ifupdown_update_connection_from_if_block(connection, block, &error); ASSERT (connection != NULL, @@ -708,11 +675,6 @@ test18_read_static_ipv6 (const char *path) /* ===== IPv6 SETTING ===== */ - ASSERT (inet_pton (AF_INET6, expected_address, &addr) > 0, - TEST18_NAME, - "failed to verify %s: couldn't convert IP address #1", - file); - s_ip6 = nm_connection_get_setting_ip6_config (connection); ASSERT (s_ip6 != NULL, TEST18_NAME, @@ -721,115 +683,85 @@ test18_read_static_ipv6 (const char *path) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, TEST18_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* IP addresses */ - ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip6) == 1, TEST18_NAME, "failed to verify %s: unexpected number of %s / %s", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); - - ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0); - ASSERT (ip6_addr, - TEST18_NAME, - "failed to verify %s: missing %s / %s #1", - file, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); - ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix, - TEST18_NAME - "failed to verify %s: unexpected %s / %s prefix", - file, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); - - ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), - &addr), - TEST18_NAME, - "failed to verify %s: unexpected %s / %s", - file, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES); + ip6_addr = nm_setting_ip_config_get_address (s_ip6, 0); + g_assert (ip6_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip6_addr), ==, "fc00::1"); + g_assert_cmpint (nm_ip_address_get_prefix (ip6_addr), ==, 64); /* DNS Addresses */ - ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip6) == 2, TEST18_NAME, "failed to verify %s: unexpected number of %s / %s values", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0, - TEST18_NAME, - "failed to verify %s: couldn't convert DNS IP address #1", - file); - - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), - &addr), + ASSERT (!strcmp (nm_setting_ip_config_get_dns (s_ip6, 0), "fc00::2"), TEST18_NAME, "failed to verify %s: unexpected %s / %s #1", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); - - ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0, - TEST18_NAME, - "failed to verify %s: couldn't convert DNS IP address #2", - file); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), - &addr), + ASSERT (!strcmp (nm_setting_ip_config_get_dns (s_ip6, 1), "fc00::3"), TEST18_NAME, "failed to verify %s: unexpected %s / %s #2", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS search domains */ - ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 2, + ASSERT (nm_setting_ip_config_get_num_dns_searches (s_ip6) == 2, TEST18_NAME, "failed to verify %s: unexpected number of %s / %s values", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 0); + tmp = nm_setting_ip_config_get_dns_search (s_ip6, 0); ASSERT (tmp != NULL, "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing %s / %s #1", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, expected_search1) == 0, "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s #1", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 1); + tmp = nm_setting_ip_config_get_dns_search (s_ip6, 1); ASSERT (tmp != NULL, TEST18_NAME, "failed to verify %s: missing %s / %s #2", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); ASSERT (strcmp (tmp, expected_search2) == 0, TEST18_NAME, "failed to verify %s: unexpected %s / %s #2", file, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); g_free (unmanaged); g_object_unref (connection); @@ -839,13 +771,10 @@ static void test19_read_static_ipv4_plen (const char *path) { NMConnection *connection; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *unmanaged = NULL; GError *error = NULL; - const char *expected_address = "10.0.0.3"; - guint32 expected_prefix = 8; - NMIP4Address *ip4_addr; - guint32 addr; + NMIPAddress *ip4_addr; #define TEST19_NAME "wired-static-verify-ip4-plen" if_block *block = NULL; @@ -853,7 +782,7 @@ test19_read_static_ipv4_plen (const char *path) init_ifparser_with_file (path, file); block = ifparser_getfirst (); - connection = nm_connection_new(); + connection = nm_simple_connection_new(); ifupdown_update_connection_from_if_block(connection, block, &error); ASSERT (connection != NULL, @@ -867,10 +796,6 @@ test19_read_static_ipv4_plen (const char *path) /* ===== IPv4 SETTING ===== */ - ASSERT (inet_pton (AF_INET, expected_address, &addr) > 0, - TEST19_NAME, "failed to verify %s: couldn't convert IP address #1", - file); - s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, TEST19_NAME, "failed to verify %s: missing %s setting", @@ -878,24 +803,16 @@ test19_read_static_ipv4_plen (const char *path) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* IP addresses */ - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 1, TEST19_NAME, "failed to verify %s: unexpected %s / %s key value", file, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES); + NM_SETTING_IP_CONFIG_ADDRESSES); - ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0); - ASSERT (ip4_addr, - TEST19_NAME, "failed to verify %s: missing IP4 address #1", - file); - - ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix, - TEST19_NAME, "failed to verify %s: unexpected IP4 address prefix", - file); - - ASSERT (nm_ip4_address_get_address (ip4_addr) == addr, - TEST19_NAME, "failed to verify %s: unexpected IP4 address: %s", - file, addr); + ip4_addr = nm_setting_ip_config_get_address (s_ip4, 0); + g_assert (ip4_addr != NULL); + g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); + g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); g_object_unref (connection); } @@ -930,14 +847,10 @@ test20_source_stanza (const char *path) int main (int argc, char **argv) { - GError *error = NULL; - #if !GLIB_CHECK_VERSION (2, 35, 0) g_type_init (); #endif - if (!nm_utils_init (&error)) - FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); nm_logging_setup ("WARN", "DEFAULT", NULL, NULL); g_test_init (&argc, &argv, NULL); diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am index cac97e7f..079c45c3 100644 --- a/src/settings/plugins/keyfile/Makefile.am +++ b/src/settings/plugins/keyfile/Makefile.am @@ -4,18 +4,15 @@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" noinst_LTLIBRARIES = \ @@ -29,7 +26,6 @@ libkeyfile_io_la_SOURCES = \ reader.h \ writer.c \ writer.h \ - errors.c \ utils.c \ utils.h \ common.h @@ -45,12 +41,7 @@ libnm_settings_plugin_keyfile_la_SOURCES = \ plugin.h libnm_settings_plugin_keyfile_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - libkeyfile-io.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) - -libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic + libkeyfile-io.la keyfiledir=$(sysconfdir)/NetworkManager/system-connections diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index 8c4d6101..8c0d11af 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -104,23 +104,17 @@ CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libkeyfile_io_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am_libkeyfile_io_la_OBJECTS = reader.lo writer.lo errors.lo utils.lo +am_libkeyfile_io_la_OBJECTS = reader.lo writer.lo utils.lo libkeyfile_io_la_OBJECTS = $(am_libkeyfile_io_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libnm_settings_plugin_keyfile_la_DEPENDENCIES = \ - $(top_builddir)/libnm-util/libnm-util.la libkeyfile-io.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +libnm_settings_plugin_keyfile_la_DEPENDENCIES = libkeyfile-io.la am_libnm_settings_plugin_keyfile_la_OBJECTS = \ nm-keyfile-connection.lo plugin.lo libnm_settings_plugin_keyfile_la_OBJECTS = \ $(am_libnm_settings_plugin_keyfile_la_OBJECTS) -libnm_settings_plugin_keyfile_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) \ - $(libnm_settings_plugin_keyfile_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -235,6 +229,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -358,6 +354,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -377,6 +374,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -403,7 +401,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -485,18 +483,15 @@ with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/config \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" noinst_LTLIBRARIES = \ @@ -510,7 +505,6 @@ libkeyfile_io_la_SOURCES = \ reader.h \ writer.c \ writer.h \ - errors.c \ utils.c \ utils.h \ common.h @@ -525,12 +519,8 @@ libnm_settings_plugin_keyfile_la_SOURCES = \ plugin.h libnm_settings_plugin_keyfile_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - libkeyfile-io.la \ - $(GLIB_LIBS) \ - $(DBUS_LIBS) + libkeyfile-io.la -libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic keyfiledir = $(sysconfdir)/NetworkManager/system-connections all: all-recursive @@ -582,7 +572,7 @@ libkeyfile-io.la: $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_DEPENDENCIES) $ $(AM_V_CCLD)$(LINK) $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_LIBADD) $(LIBS) libnm-settings-plugin-keyfile.la: $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_DEPENDENCIES) $(EXTRA_libnm_settings_plugin_keyfile_la_DEPENDENCIES) - $(AM_V_CCLD)$(libnm_settings_plugin_keyfile_la_LINK) $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -590,7 +580,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-keyfile-connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Plo@am__quote@ diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h index 4faa5a84..db6569e5 100644 --- a/src/settings/plugins/keyfile/common.h +++ b/src/settings/plugins/keyfile/common.h @@ -30,8 +30,5 @@ #define VPN_SECRETS_GROUP "vpn-secrets" -#define KEYFILE_PLUGIN_ERROR (keyfile_plugin_error_quark ()) -GQuark keyfile_plugin_error_quark (void); - #endif /* __COMMON_H__ */ diff --git a/src/settings/plugins/keyfile/errors.c b/src/settings/plugins/keyfile/errors.c deleted file mode 100644 index e2e97690..00000000 --- a/src/settings/plugins/keyfile/errors.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 - 2010 Red Hat, Inc. - */ - -#include -#include "common.h" - -GQuark -keyfile_plugin_error_quark (void) -{ - static GQuark error_quark = 0; - - if (G_UNLIKELY (error_quark == 0)) - error_quark = g_quark_from_static_string ("keyfile-plugin-error-quark"); - - return error_quark; -} - - diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c index 4ef761c6..c852f028 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.c +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c @@ -19,9 +19,11 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include -#include +#include #include #include @@ -63,7 +65,7 @@ nm_keyfile_connection_new (NMConnection *source, uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); if (!uuid) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Connection in file %s had no UUID", full_path); g_object_unref (tmp); return NULL; @@ -166,11 +168,7 @@ nm_keyfile_connection_init (NMKeyfileConnection *connection) static void finalize (GObject *object) { - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - - nm_connection_clear_secrets (NM_CONNECTION (object)); - - g_free (priv->path); + g_free (NM_KEYFILE_CONNECTION_GET_PRIVATE (object)->path); G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object); } @@ -184,7 +182,7 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); /* Virtual methods */ - object_class->finalize = finalize; + object_class->finalize = finalize; settings_class->commit_changes = commit_changes; settings_class->delete = do_delete; } diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h index 07dcafcb..135bb49f 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.h +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -19,8 +19,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#ifndef NM_KEYFILE_CONNECTION_H -#define NM_KEYFILE_CONNECTION_H +#ifndef __NETWORKMANAGER_KEYFILE_CONNECTION_H__ +#define __NETWORKMANAGER_KEYFILE_CONNECTION_H__ #include @@ -52,4 +52,4 @@ void nm_keyfile_connection_set_path (NMKeyfileConnection *self, const cha G_END_DECLS -#endif /* NM_KEYFILE_CONNECTION_H */ +#endif /* __NETWORKMANAGER_KEYFILE_CONNECTION_H__ */ diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index 10c83971..371fa47a 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -19,11 +19,11 @@ * Copyright (C) 2008 - 2013 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include -#include #include #include @@ -37,6 +37,7 @@ #include #include #include +#include "nm-core-internal.h" #include "plugin.h" #include "nm-system-config-interface.h" @@ -373,20 +374,13 @@ static GSList * get_connections (NMSystemConfigInterface *config) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); - GHashTableIter iter; - gpointer data = NULL; - GSList *list = NULL; if (!priv->initialized) { setup_monitoring (config); read_connections (config); priv->initialized = TRUE; } - - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - list = g_slist_prepend (list, data); - return list; + return _nm_utils_hash_values_to_slist (priv->connections); } static gboolean @@ -496,12 +490,12 @@ get_unmanaged_specs (NMSystemConfigInterface *config) char **udis; int i; - udis = g_strsplit (str, ";", -1); + udis = g_strsplit_set (str, ";,", -1); g_free (str); for (i = 0; udis[i] != NULL; i++) { /* Verify unmanaged specification and add it to the list */ - if (!strncmp (udis[i], "mac:", 4) && nm_utils_hwaddr_valid (udis[i] + 4)) { + if (!strncmp (udis[i], "mac:", 4) && nm_utils_hwaddr_valid (udis[i] + 4, -1)) { specs = g_slist_append (specs, udis[i]); } else if (!strncmp (udis[i], "interface-name:", 15) && nm_utils_iface_valid_name (udis[i] + 15)) { specs = g_slist_append (specs, udis[i]); diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h index 5f437390..48579785 100644 --- a/src/settings/plugins/keyfile/plugin.h +++ b/src/settings/plugins/keyfile/plugin.h @@ -41,8 +41,6 @@ typedef struct { GType sc_plugin_keyfile_get_type (void); -GQuark keyfile_plugin_error_quark (void); - GObject *nm_settings_keyfile_plugin_new (void); #endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 735f8c28..1d2ecdad 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -19,27 +19,17 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include +#include "nm-core-internal.h" #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" #include "nm-system-config-interface.h" @@ -47,6 +37,8 @@ #include "reader.h" #include "common.h" #include "utils.h" +#include "nm-core-internal.h" +#include "NetworkManagerUtils.h" /* Some setting properties also contain setting names, such as * NMSettingConnection's 'type' property (which specifies the base type of the @@ -119,135 +111,77 @@ get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *ou } static gpointer -build_ip4_address_or_route (const char *key_name, const char *address_str, guint32 plen, const char *gateway_str, const char *metric_str, gboolean route) +build_address (int family, const char *address_str, guint32 plen) { - GArray *result; - guint32 addr; - guint32 address = 0; - guint32 gateway = 0; - guint32 metric = 0; - int err; + NMIPAddress *addr; + GError *error = NULL; g_return_val_if_fail (address_str, NULL); - /* Address */ - err = inet_pton (AF_INET, address_str, &addr); - if (err <= 0) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv4 address '%s'", __func__, address_str); - return NULL; - } - address = addr; - - /* Gateway */ - if (gateway_str && gateway_str[0]) { - err = inet_pton (AF_INET, gateway_str, &addr); - if (err <= 0) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv4 gateway '%s'", __func__, gateway_str); - return NULL; - } - gateway = addr; - } - else - gateway = 0; - - /* parse metric, default to 0 */ - if (metric_str) { - if (!get_one_int (metric_str, G_MAXUINT32, key_name, &metric)) - return NULL; + addr = nm_ip_address_new (family, address_str, plen, &error); + if (!addr) { + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s address: %s", __func__, + family == AF_INET ? "IPv4" : "IPv6", + error->message); + g_error_free (error); } - result = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3 + !!route); - g_array_append_val (result, address); - g_array_append_val (result, plen); - g_array_append_val (result, gateway); - if (route) - g_array_append_val (result, metric); - - return result; + return addr; } static gpointer -build_ip6_address_or_route (const char *key_name, const char *address_str, guint32 plen, const char *gateway_str, const char *metric_str, gboolean route) +build_route (int family, + const char *dest_str, guint32 plen, + const char *gateway_str, const char *metric_str, + const char *key_name) { - GValueArray *result; - struct in6_addr addr; - GByteArray *address; - GByteArray *gateway; + NMIPRoute *route; guint32 metric = 0; - GValue value = G_VALUE_INIT; - int err; - - g_return_val_if_fail (address_str, NULL); + GError *error = NULL; - result = g_value_array_new (3); + g_return_val_if_fail (plen, NULL); + g_return_val_if_fail (dest_str, NULL); - /* add address */ - err = inet_pton (AF_INET6, address_str, &addr); - if (err <= 0) { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv6 address '%s'", __func__, address_str); - goto error_out; - } - address = g_byte_array_new (); - g_byte_array_append (address, (guint8 *) addr.s6_addr, 16); - g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_take_boxed (&value, address); - g_value_array_append (result, &value); - g_value_unset (&value); - - /* add prefix length */ - g_value_init (&value, G_TYPE_UINT); - g_value_set_uint (&value, plen); - g_value_array_append (result, &value); - g_value_unset (&value); - - /* add gateway */ + /* Next hop */ if (gateway_str && gateway_str[0]) { - err = inet_pton (AF_INET6, gateway_str, &addr); - if (err <= 0) { + if (!nm_utils_ipaddr_valid (family, gateway_str)) { /* Try workaround for routes written by broken keyfile writer. * Due to bug bgo#719851, an older version of writer would have * written "a:b:c:d::/plen,metric" if the gateway was ::, instead * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric" - * Try workaround by interepeting gateway_str as metric to accept such + * Try workaround by interpreting gateway_str as metric to accept such * invalid routes. This broken syntax should not be not officially * supported. **/ - if (route && !metric_str && get_one_int (gateway_str, G_MAXUINT32, NULL, &metric)) - addr = in6addr_any; + if ( family == AF_INET6 + && !metric_str + && get_one_int (gateway_str, G_MAXUINT32, NULL, &metric)) + gateway_str = NULL; else { - nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv6 gateway '%s'", __func__, gateway_str); - goto error_out; + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid gateway '%s'", __func__, gateway_str); + return NULL; } } } else - addr = in6addr_any; + gateway_str = NULL; /* parse metric, default to 0 */ if (metric_str) { if (!get_one_int (metric_str, G_MAXUINT32, key_name, &metric)) - goto error_out; + return NULL; } - gateway = g_byte_array_new (); - g_byte_array_append (gateway, (guint8 *) addr.s6_addr, 16); - g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_take_boxed (&value, gateway); - g_value_array_append (result, &value); - g_value_unset (&value); - - /* add metric (for routing) */ - if (route) { - g_value_init (&value, G_TYPE_UINT); - g_value_set_uint (&value, metric); - g_value_array_append (result, &value); - g_value_unset (&value); + route = nm_ip_route_new (family, dest_str, plen, gateway_str, + metric ? (gint64) metric : -1, + &error); + if (!route) { + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s route: %s", __func__, + family == AF_INET ? "IPv4" : "IPv6", + error->message); + g_error_free (error); } - return result; - -error_out: - g_value_array_free (result); - return NULL; + return route; } /* On success, returns pointer to the zero-terminated field (original @current). @@ -334,17 +268,16 @@ read_field (char **current, char **error, const char *characters, const char *de * changed. The default for IPv4 is now 24, which is the closest * IPv4 equivalent. These defaults may just as well be changed to * match the iproute2 defaults (32 for IPv4 and 128 for IPv6). - * - * The returned result is GArray for IPv4 and GValueArray for IPv6. */ static gpointer read_one_ip_address_or_route (GKeyFile *file, - const char *setting_name, - const char *key_name, - gboolean ipv6, - gboolean route) + const char *setting_name, + const char *key_name, + gboolean ipv6, + gboolean route, + char **out_gateway) { - guint32 plen; + guint32 plen = G_MAXUINT32; gpointer result; char *address_str, *plen_str, *gateway_str, *metric_str, *value, *current, *error; @@ -394,22 +327,33 @@ read_one_ip_address_or_route (GKeyFile *file, } } +#define DEFAULT_PREFIX(for_route, for_ipv6) ( (for_route) ? ( (for_ipv6) ? 128 : 24 ) : ( (for_ipv6) ? 64 : 24 ) ) + /* parse plen, fallback to defaults */ - if (plen_str) - g_return_val_if_fail (get_one_int (plen_str, ipv6 ? 128 : 32, - key_name, &plen), NULL); - else { - if (route) - plen = ipv6 ? 128 : 24; - else - plen = ipv6 ? 64 : 24; + if (plen_str) { + if (!get_one_int (plen_str, ipv6 ? 128 : 32, key_name, &plen) + || (route && plen == 0)) { + plen = DEFAULT_PREFIX (route, ipv6); + nm_log_warn (LOGD_SETTINGS, "keyfile: invalid prefix length '%s' in '%s.%s', defaulting to %d", + plen_str, setting_name, key_name, plen); + } + } else { + plen = DEFAULT_PREFIX (route, ipv6); nm_log_warn (LOGD_SETTINGS, "keyfile: Missing prefix length in '%s.%s', defaulting to %d", setting_name, key_name, plen); } /* build the appropriate data structure for NetworkManager settings */ - result = (ipv6 ? build_ip6_address_or_route : build_ip4_address_or_route) ( - key_name, address_str, plen, gateway_str, metric_str, route); + if (route) { + result = build_route (ipv6 ? AF_INET6 : AF_INET, + address_str, plen, gateway_str, metric_str, + key_name); + } else { + result = build_address (ipv6 ? AF_INET6 : AF_INET, + address_str, plen); + if (out_gateway && gateway_str) + *out_gateway = g_strdup (gateway_str); + } g_free (value); return result; @@ -427,13 +371,16 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi static const char *key_names_routes[] = { "route", "routes", NULL }; static const char *key_names_addresses[] = { "address", "addresses", NULL }; const char **key_names = routes ? key_names_routes : key_names_addresses; + char *gateway = NULL; GPtrArray *list; + GDestroyNotify free_func; int i; - G_GNUC_BEGIN_IGNORE_DEPRECATIONS; - list = g_ptr_array_new_with_free_func ( - ipv6 ? (GDestroyNotify) g_value_array_free : (GDestroyNotify) g_array_unref); - G_GNUC_END_IGNORE_DEPRECATIONS; + if (routes) + free_func = (GDestroyNotify) nm_ip_route_unref; + else + free_func = (GDestroyNotify) nm_ip_address_unref; + list = g_ptr_array_new_with_free_func (free_func); for (i = -1; i < 1000; i++) { const char **key_basename; @@ -448,8 +395,8 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi else key_name = g_strdup (*key_basename); - item = read_one_ip_address_or_route (keyfile, setting_name, key_name, ipv6, routes); - + item = read_one_ip_address_or_route (keyfile, setting_name, key_name, ipv6, routes, + gateway ? NULL : &gateway); if (item) g_ptr_array_add (list, item); @@ -460,6 +407,11 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi if (list->len >= 1) g_object_set (setting, key, list, NULL); + if (gateway) { + g_object_set (setting, "gateway", gateway, NULL); + g_free (gateway); + } + g_ptr_array_unref (list); } @@ -467,7 +419,7 @@ static void ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - GArray *array = NULL; + GPtrArray *array; gsize length; char **list, **iter; int ret; @@ -476,7 +428,7 @@ ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch if (!list || !g_strv_length (list)) return; - array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); + array = g_ptr_array_sized_new (length + 1); for (iter = list; *iter; iter++) { guint32 addr; @@ -486,14 +438,13 @@ ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch continue; } - g_array_append_val (array, addr); + g_ptr_array_add (array, *iter); } - g_strfreev (list); + g_ptr_array_add (array, NULL); - if (array) { - g_object_set (setting, key, array, NULL); - g_array_unref (array); - } + g_object_set (setting, key, array->pdata, NULL); + g_ptr_array_unref (array); + g_strfreev (list); } static void @@ -509,10 +460,9 @@ ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch if (!list || !g_strv_length (list)) return; - array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_byte_array_unref); + array = g_ptr_array_sized_new (length + 1); for (iter = list; *iter; iter++) { - GByteArray *byte_array; struct in6_addr addr; ret = inet_pton (AF_INET6, *iter, &addr); @@ -520,24 +470,21 @@ ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter); continue; } - byte_array = g_byte_array_new (); - g_byte_array_append (byte_array, (guint8 *) addr.s6_addr, 16); - g_ptr_array_add (array, byte_array); + g_ptr_array_add (array, *iter); } - g_strfreev (list); + g_ptr_array_add (array, NULL); - if (array) { - g_object_set (setting, key, array, NULL); - g_ptr_array_unref (array); - } + g_object_set (setting, key, array->pdata, NULL); + g_ptr_array_unref (array); + g_strfreev (list); } static void mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path, gsize enforce_length) { const char *setting_name = nm_setting_get_name (setting); - char *tmp_string = NULL, *p; + char *tmp_string = NULL, *p, *mac_str; gint *tmp_list; GByteArray *array = NULL; gsize length; @@ -557,7 +504,7 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons /* If we found enough it's probably a string-format MAC address */ array = g_byte_array_sized_new (i+1); g_byte_array_set_size (array, i+1); - if (!nm_utils_hwaddr_aton_len (tmp_string, array->data, array->len)) { + if (!nm_utils_hwaddr_aton (tmp_string, array->data, array->len)) { g_byte_array_unref (array); array = NULL; } @@ -590,13 +537,16 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons g_free (tmp_list); } - if (array) { - g_object_set (setting, key, array, NULL); - g_byte_array_free (array, TRUE); - } else { + if (!array) { nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid MAC address for %s / %s", __func__, setting_name, key); + return; } + + mac_str = nm_utils_hwaddr_ntoa (array->data, array->len); + g_object_set (setting, key, mac_str, NULL); + g_free (mac_str); + g_byte_array_free (array, TRUE); } static void @@ -628,11 +578,12 @@ read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) continue; if (NM_IS_SETTING_VPN (setting)) { - if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE) && strcmp (*iter, NM_SETTING_VPN_USER_NAME)) + /* Add any item that's not a class property to the data hash */ + if (!g_object_class_find_property (G_OBJECT_GET_CLASS (setting), *iter)) nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value); } if (NM_IS_SETTING_BOND (setting)) { - if (strcmp (*iter, NM_SETTING_BOND_INTERFACE_NAME)) + if (strcmp (*iter, "interface-name")) nm_setting_bond_add_option (NM_SETTING_BOND (setting), *iter, value); } g_free (value); @@ -655,12 +606,12 @@ unescape_semicolons (char *str) } } -static GByteArray * -get_uchar_array (GKeyFile *keyfile, - const char *setting_name, - const char *key, - gboolean zero_terminate, - gboolean unescape_semicolon) +static GBytes * +get_bytes (GKeyFile *keyfile, + const char *setting_name, + const char *key, + gboolean zero_terminate, + gboolean unescape_semicolon) { GByteArray *array = NULL; char *tmp_string; @@ -714,21 +665,21 @@ get_uchar_array (GKeyFile *keyfile, if (array->len == 0) { g_byte_array_free (array, TRUE); - array = NULL; - } - return array; + return NULL; + } else + return g_byte_array_free_to_bytes (array); } static void ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - GByteArray *array; + GBytes *bytes; - array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE); - if (array) { - g_object_set (setting, key, array, NULL); - g_byte_array_free (array, TRUE); + bytes = get_bytes (keyfile, setting_name, key, FALSE, TRUE); + if (bytes) { + g_object_set (setting, key, bytes, NULL); + g_bytes_unref (bytes); } else { nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid SSID for %s / %s", __func__, setting_name, key); @@ -739,12 +690,12 @@ static void password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - GByteArray *array; + GBytes *bytes; - array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE); - if (array) { - g_object_set (setting, key, array, NULL); - g_byte_array_free (array, TRUE); + bytes = get_bytes (keyfile, setting_name, key, FALSE, TRUE); + if (bytes) { + g_object_set (setting, key, bytes, NULL); + g_bytes_unref (bytes); } else { nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid raw password for %s / %s", __func__, setting_name, key); @@ -752,7 +703,7 @@ password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, con } static char * -get_cert_path (const char *keyfile_path, GByteArray *cert_path) +get_cert_path (const char *keyfile_path, const guint8 *cert_path, gsize cert_path_len) { const char *base; char *p = NULL, *path, *dirname, *tmp; @@ -760,8 +711,8 @@ get_cert_path (const char *keyfile_path, GByteArray *cert_path) g_return_val_if_fail (keyfile_path != NULL, NULL); g_return_val_if_fail (cert_path != NULL, NULL); - base = path = g_malloc0 (cert_path->len + 1); - memcpy (path, cert_path->data, cert_path->len); + base = path = g_malloc0 (cert_path_len + 1); + memcpy (path, cert_path, cert_path_len); if (path[0] == '/') return path; @@ -794,37 +745,46 @@ has_cert_ext (const char *path) } static gboolean -handle_as_scheme (GByteArray *array, NMSetting *setting, const char *key) +handle_as_scheme (GBytes *bytes, NMSetting *setting, const char *key) { + const guint8 *data; + gsize data_len; + + data = g_bytes_get_data (bytes, &data_len); + /* It's the PATH scheme, can just set plain data */ - if ( (array->len > strlen (SCHEME_PATH)) - && g_str_has_prefix ((const char *) array->data, SCHEME_PATH) - && (array->data[array->len - 1] == '\0')) { - g_object_set (setting, key, array, NULL); + if ( (data_len > strlen (SCHEME_PATH)) + && g_str_has_prefix ((const char *) data, SCHEME_PATH) + && (data[data_len - 1] == '\0')) { + g_object_set (setting, key, bytes, NULL); return TRUE; } return FALSE; } static gboolean -handle_as_path (GByteArray *array, +handle_as_path (GBytes *bytes, NMSetting *setting, const char *key, const char *keyfile_path) { - gsize validate_len = array->len; - GByteArray *val; + const guint8 *data; + gsize data_len; + gsize validate_len; char *path; gboolean exists, success = FALSE; - if (array->len > 500 || array->len < 1) + data = g_bytes_get_data (bytes, &data_len); + if (data_len > 500 || data_len < 1) return FALSE; /* If there's a trailing NULL tell g_utf8_validate() to to until the NULL */ - if (array->data[array->len - 1] == '\0') + if (data[data_len - 1] == '\0') validate_len = -1; + else + validate_len = data_len; - if (g_utf8_validate ((const char *) array->data, validate_len, NULL) == FALSE) + if (g_utf8_validate ((const char *) data, validate_len, NULL) == FALSE) return FALSE; /* Might be a bare path without the file:// prefix; in that case @@ -832,18 +792,22 @@ handle_as_path (GByteArray *array, * relative path to the current directory. */ - path = get_cert_path (keyfile_path, array); + path = get_cert_path (keyfile_path, data, data_len); exists = g_file_test (path, G_FILE_TEST_EXISTS); if ( exists - || memchr (array->data, '/', array->len) + || memchr (data, '/', data_len) || has_cert_ext (path)) { + GByteArray *tmp; + GBytes *val; + /* Construct the proper value as required for the PATH scheme */ - val = g_byte_array_sized_new (strlen (SCHEME_PATH) + strlen (path) + 1); - g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); - g_byte_array_append (val, (const guint8 *) path, strlen (path)); - g_byte_array_append (val, (const guint8 *) "\0", 1); + tmp = g_byte_array_sized_new (strlen (SCHEME_PATH) + strlen (path) + 1); + g_byte_array_append (tmp, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH)); + g_byte_array_append (tmp, (const guint8 *) path, strlen (path)); + g_byte_array_append (tmp, (const guint8 *) "\0", 1); + val = g_byte_array_free_to_bytes (tmp); g_object_set (setting, key, val, NULL); - g_byte_array_free (val, TRUE); + g_bytes_unref (val); success = TRUE; /* Warn if the certificate didn't exist */ @@ -859,28 +823,78 @@ static void cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - GByteArray *array; + GBytes *bytes; gboolean success = FALSE; - array = get_uchar_array (keyfile, setting_name, key, TRUE, FALSE); - if (array && array->len > 0) { + bytes = get_bytes (keyfile, setting_name, key, TRUE, FALSE); + if (bytes) { /* Try as a path + scheme (ie, starts with "file://") */ - success = handle_as_scheme (array, setting, key); + success = handle_as_scheme (bytes, setting, key); /* If not, it might be a plain path */ if (success == FALSE) - success = handle_as_path (array, setting, key, keyfile_path); + success = handle_as_path (bytes, setting, key, keyfile_path); /* If neither of those two, assume blob with certificate data */ if (success == FALSE) - g_object_set (setting, key, array, NULL); + g_object_set (setting, key, bytes, NULL); } else { nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid key/cert value for %s / %s", __func__, setting_name, key); } - if (array) - g_byte_array_free (array, TRUE); + if (bytes) + g_bytes_unref (bytes); +} + +static void +parity_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + NMSettingSerialParity parity; + int int_val; + char *str_val; + + /* Keyfile traditionally stored this as the ASCII value for 'E', 'o', or 'n'. + * We now accept either that or the (case-insensitive) character itself (but + * still always write it the old way, for backward compatibility). + */ + int_val = nm_keyfile_plugin_kf_get_integer (keyfile, setting_name, key, NULL); + if (!int_val) { + str_val = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); + if (str_val) { + if (str_val[0] && !str_val[1]) + int_val = str_val[0]; + else { + /* This will hit the warning below */ + int_val = 'X'; + } + } + } + + if (!int_val) + return; + + switch (int_val) { + case 'E': + case 'e': + parity = NM_SETTING_SERIAL_PARITY_EVEN; + break; + case 'O': + case 'o': + parity = NM_SETTING_SERIAL_PARITY_ODD; + break; + case 'N': + case 'n': + parity = NM_SETTING_SERIAL_PARITY_NONE; + break; + default: + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid value for %s / %s", + __func__, setting_name, key); + return; + } + + g_object_set (setting, key, parity, NULL); } typedef struct { @@ -906,27 +920,27 @@ static KeyParser key_parsers[] = { TRUE, mac_address_parser_ETHER }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES, + NM_SETTING_IP_CONFIG_ADDRESSES, FALSE, ip_address_or_route_parser }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES, + NM_SETTING_IP_CONFIG_ADDRESSES, FALSE, ip_address_or_route_parser }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES, + NM_SETTING_IP_CONFIG_ROUTES, FALSE, ip_address_or_route_parser }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ROUTES, + NM_SETTING_IP_CONFIG_ROUTES, FALSE, ip_address_or_route_parser }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS, + NM_SETTING_IP_CONFIG_DNS, FALSE, ip4_dns_parser }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS, + NM_SETTING_IP_CONFIG_DNS, FALSE, ip6_dns_parser }, { NM_SETTING_WIRED_SETTING_NAME, @@ -993,6 +1007,10 @@ static KeyParser key_parsers[] = { NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, TRUE, cert_parser }, + { NM_SETTING_SERIAL_SETTING_NAME, + NM_SETTING_SERIAL_PARITY, + TRUE, + parity_parser }, { NULL, NULL, FALSE } }; @@ -1010,6 +1028,7 @@ read_one_setting_value (NMSetting *setting, { ReadInfo *info = user_data; const char *setting_name; + int errsv; GType type; GError *err = NULL; gboolean check_for_key = TRUE; @@ -1110,9 +1129,22 @@ read_one_setting_value (NMSetting *setting, uint_val = g_ascii_strtoull (tmp_str, NULL, 10); g_free (tmp_str); g_object_set (setting, key, uint_val, NULL); - } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { + } else if (type == G_TYPE_INT64) { + char *tmp_str; + gint64 int_val; + + tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, NULL); + int_val = nm_utils_ascii_str_to_int64 (tmp_str, 10, G_MININT64, G_MAXINT64, 0); + errsv = errno; + if (errsv) + nm_log_warn (LOGD_SETTINGS, "Invalid int64 value (%s)", tmp_str); + else + g_object_set (setting, key, int_val, NULL); + g_free (tmp_str); + } else if (type == G_TYPE_BYTES) { gint *tmp; GByteArray *array; + GBytes *bytes; gsize length; int i; @@ -1131,31 +1163,45 @@ read_one_setting_value (NMSetting *setting, g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); } - g_object_set (setting, key, array, NULL); - g_byte_array_free (array, TRUE); + bytes = g_byte_array_free_to_bytes (array); + g_object_set (setting, key, bytes, NULL); + g_bytes_unref (bytes); g_free (tmp); - } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { + } else if (type == G_TYPE_STRV) { gchar **sa; gsize length; - int i; - GSList *list = NULL; sa = nm_keyfile_plugin_kf_get_string_list (info->keyfile, setting_name, key, &length, NULL); - for (i = 0; i < length; i++) - list = g_slist_prepend (list, sa[i]); - - list = g_slist_reverse (list); - g_object_set (setting, key, list, NULL); - - g_slist_free (list); + g_object_set (setting, key, sa, NULL); g_strfreev (sa); - } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { + } else if (type == G_TYPE_HASH_TABLE) { read_hash_of_string (info->keyfile, setting, key); - } else if (type == DBUS_TYPE_G_UINT_ARRAY) { + } else if (type == G_TYPE_ARRAY) { if (!read_array_of_uint (info->keyfile, setting, key)) { nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", setting_name, key, G_VALUE_TYPE_NAME (value)); } + } else if (G_VALUE_HOLDS_FLAGS (value)) { + guint64 uint_val; + + /* Flags are guint but GKeyFile has no uint reader, just uint64 */ + uint_val = nm_keyfile_plugin_kf_get_uint64 (info->keyfile, setting_name, key, &err); + if (!err) { + if (uint_val <= G_MAXUINT) + g_object_set (setting, key, (guint) uint_val, NULL); + else { + nm_log_warn (LOGD_SETTINGS, "Too large FLAGS property (read): '%s/%s' : '%s'", + setting_name, key, G_VALUE_TYPE_NAME (value)); + } + } + g_clear_error (&err); + } else if (G_VALUE_HOLDS_ENUM (value)) { + gint int_val; + + int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, &err); + if (!err) + g_object_set (setting, key, (gint) int_val, NULL); + g_clear_error (&err); } else { nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", setting_name, key, G_VALUE_TYPE_NAME (value)); @@ -1165,22 +1211,27 @@ read_one_setting_value (NMSetting *setting, static NMSetting * read_setting (GKeyFile *file, const char *keyfile_path, const char *group) { - NMSetting *setting; + NMSetting *setting = NULL; ReadInfo info = { file, keyfile_path }; const char *alias; + GType type; alias = nm_keyfile_plugin_get_setting_name_for_alias (group); - setting = nm_connection_create_setting (alias ? alias : group); - if (setting) + if (alias) + group = alias; + + type = nm_setting_lookup_type (group); + if (type) { + setting = g_object_new (type, NULL); nm_setting_enumerate_values (setting, read_one_setting_value, &info); - else + } else nm_log_warn (LOGD_SETTINGS, "Invalid setting name '%s'", group); return setting; } static void -read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) +read_vpn_secrets (GKeyFile *file, NMSettingVpn *s_vpn) { char **keys, **iter; @@ -1197,30 +1248,6 @@ read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) g_strfreev (keys); } -static void -ensure_slave_setting (NMConnection *connection) -{ - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - const char *slave_type; - GType slave_gtype = G_TYPE_INVALID; - NMSetting *setting; - - slave_type = nm_setting_connection_get_slave_type (s_con); - if (!slave_type) - return; - - if (g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) == 0) - slave_gtype = NM_TYPE_SETTING_BRIDGE_PORT; - else if (g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME) == 0) - slave_gtype = NM_TYPE_SETTING_TEAM_PORT; - - if (slave_gtype != G_TYPE_INVALID && !nm_connection_get_setting (connection, slave_gtype)) { - setting = (NMSetting *) g_object_new (slave_gtype, NULL); - g_assert (setting); - nm_connection_add_setting (connection, setting); - } -} - NMConnection * nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) { @@ -1234,11 +1261,10 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) gsize length; int i; gboolean vpn_secrets = FALSE; - const char *ctype; GError *verify_error = NULL; if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) { - g_set_error_literal (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "File did not exist or was not a regular file"); return NULL; } @@ -1246,7 +1272,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) bad_permissions = statbuf.st_mode & 0077; if (bad_permissions) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "File permissions (%o) were insecure", statbuf.st_mode); return NULL; @@ -1256,7 +1282,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) goto out; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); groups = g_key_file_get_groups (key_file, &length); for (i = 0; i < length; i++) { @@ -1271,36 +1297,50 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) nm_connection_add_setting (connection, setting); } - /* Make sure that we have the base device type and slave type settings - * even if the keyfile didn't include it, which can happen when the - * setting in question is all default values (like ethernet where - * the MAC address isn't given, or VLAN when the VLAN ID is zero, or - * bridge port with all default settings). - */ s_con = nm_connection_get_setting_connection (connection); - if (s_con) { - ctype = nm_setting_connection_get_connection_type (s_con); - if (ctype) { - setting = nm_connection_get_setting_by_name (connection, ctype); - if (!setting) { - NMSetting *base_setting; - GType base_setting_type; - - base_setting_type = nm_connection_lookup_setting_type (ctype); - if (base_setting_type != G_TYPE_INVALID) { - base_setting = (NMSetting *) g_object_new (base_setting_type, NULL); - g_assert (base_setting); - nm_connection_add_setting (connection, base_setting); - } - } - } + if (!s_con) { + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + } + + /* Make sure that we have 'id' even if not explictly specified in the keyfile */ + if (!nm_setting_connection_get_id (s_con)) { + char *base_name; - ensure_slave_setting (connection); + base_name = g_path_get_basename (filename); + g_object_set (s_con, NM_SETTING_CONNECTION_ID, base_name, NULL); + g_free (base_name); + } + + /* Make sure that we have 'uuid' even if not explictly specified in the keyfile */ + if (!nm_setting_connection_get_uuid (s_con)) { + char *hashed_uuid; + + hashed_uuid = nm_utils_uuid_generate_from_strings ("keyfile", filename, NULL); + g_object_set (s_con, NM_SETTING_CONNECTION_UUID, hashed_uuid, NULL); + g_free (hashed_uuid); + } + + /* Make sure that we have 'interface-name' even if it was specified in the + * "wrong" (ie, deprecated) group. + */ + if ( !nm_setting_connection_get_interface_name (s_con) + && nm_setting_connection_get_connection_type (s_con)) { + char *interface_name; + + interface_name = g_key_file_get_string (key_file, + nm_setting_connection_get_connection_type (s_con), + "interface-name", + NULL); + if (interface_name) { + g_object_set (s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL); + g_free (interface_name); + } } /* Handle vpn secrets after the 'vpn' setting was read */ if (vpn_secrets) { - NMSettingVPN *s_vpn; + NMSettingVpn *s_vpn; s_vpn = nm_connection_get_setting_vpn (connection); if (s_vpn) @@ -1309,12 +1349,11 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) g_strfreev (groups); - /* Verify the connection */ - if (!nm_connection_verify (connection, &verify_error)) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, - "invalid or missing connection property '%s/%s'", - verify_error ? g_type_name (nm_connection_lookup_setting_type_by_quark (verify_error->domain)) : "(unknown)", - (verify_error && verify_error->message) ? verify_error->message : "(unknown)"); + /* Normalize and verify the connection */ + if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "invalid connection: %s", + verify_error->message); g_clear_error (&verify_error); g_object_unref (connection); connection = NULL; diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am index fae6e4ea..20b9820c 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.am +++ b/src/settings/plugins/keyfile/tests/Makefile.am @@ -6,19 +6,16 @@ SUBDIRS=keyfiles AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(srcdir)/../ \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(POLKIT_CFLAGS) \ $(CODE_COVERAGE_CFLAGS) \ -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" \ @@ -30,13 +27,10 @@ test_keyfile_SOURCES = \ test-keyfile.c \ ../reader.c \ ../writer.c \ - ../errors.c \ ../utils.c test_keyfile_LDADD = \ $(top_builddir)/src/libNetworkManager.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ - $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ $(CODE_COVERAGE_LDFLAGS) diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index f7b4b62a..8530bf8c 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -105,16 +105,14 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am__test_keyfile_SOURCES_DIST = test-keyfile.c ../reader.c ../writer.c \ - ../errors.c ../utils.c + ../utils.c @ENABLE_TESTS_TRUE@am_test_keyfile_OBJECTS = test-keyfile.$(OBJEXT) \ @ENABLE_TESTS_TRUE@ reader.$(OBJEXT) writer.$(OBJEXT) \ -@ENABLE_TESTS_TRUE@ errors.$(OBJEXT) utils.$(OBJEXT) +@ENABLE_TESTS_TRUE@ utils.$(OBJEXT) test_keyfile_OBJECTS = $(am_test_keyfile_OBJECTS) am__DEPENDENCIES_1 = @ENABLE_TESTS_TRUE@test_keyfile_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ @ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -254,6 +252,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -377,6 +377,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -396,6 +397,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -422,7 +424,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -504,19 +506,16 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@SUBDIRS = keyfiles @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/include \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-core \ +@ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-core \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src \ -@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/logging \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ @ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ -@ENABLE_TESTS_TRUE@ $(POLKIT_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_CFLAGS) \ @ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ +@ENABLE_TESTS_TRUE@ -DNETWORKMANAGER_COMPILATION \ @ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ @ENABLE_TESTS_TRUE@ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" \ @@ -526,13 +525,10 @@ with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@ test-keyfile.c \ @ENABLE_TESTS_TRUE@ ../reader.c \ @ENABLE_TESTS_TRUE@ ../writer.c \ -@ENABLE_TESTS_TRUE@ ../errors.c \ @ENABLE_TESTS_TRUE@ ../utils.c @ENABLE_TESTS_TRUE@test_keyfile_LDADD = \ @ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ -@ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ @ENABLE_TESTS_TRUE@ $(DBUS_LIBS) \ @ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_LDFLAGS) @@ -590,7 +586,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-keyfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ @@ -645,20 +640,6 @@ writer.obj: ../writer.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o writer.obj `if test -f '../writer.c'; then $(CYGPATH_W) '../writer.c'; else $(CYGPATH_W) '$(srcdir)/../writer.c'; fi` -errors.o: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.o -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c - -errors.obj: ../errors.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.obj -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` - utils.o: ../utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils.o -MD -MP -MF $(DEPDIR)/utils.Tpo -c -o utils.o `test -f '../utils.c' || echo '$(srcdir)/'`../utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utils.Tpo $(DEPDIR)/utils.Po diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT index cc8a9ee3..162bf72e 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT +++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT @@ -16,6 +16,7 @@ apn=ISP.CINGULAR [serial] baud=115200 +parity=o [bluetooth] bdaddr=00:11:22:33:44:55 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain index 236cca0e..902b8427 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain +++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain @@ -18,3 +18,4 @@ pin=2345 [serial] baud=115200 +parity=111 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am index 576164d2..4ca4c3fa 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am @@ -21,7 +21,16 @@ KEYFILES = \ Test_Bridge_Component \ Test_New_Wired_Group_Name \ Test_New_Wireless_Group_Names \ - Test_Missing_Vlan_Setting + Test_minimal_1 \ + Test_minimal_2 \ + Test_minimal_slave_1 \ + Test_minimal_slave_2 \ + Test_minimal_slave_3 \ + Test_minimal_slave_4 \ + Test_Missing_Vlan_Setting \ + Test_Missing_ID_UUID \ + Test_Enum_Property \ + Test_Flags_Property CERTS = \ test-ca-cert.pem \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index 05660e3e..bc522b1b 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -129,6 +129,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -252,6 +254,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -271,6 +274,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -297,7 +301,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -399,7 +403,16 @@ KEYFILES = \ Test_Bridge_Component \ Test_New_Wired_Group_Name \ Test_New_Wireless_Group_Names \ - Test_Missing_Vlan_Setting + Test_minimal_1 \ + Test_minimal_2 \ + Test_minimal_slave_1 \ + Test_minimal_slave_2 \ + Test_minimal_slave_3 \ + Test_minimal_slave_4 \ + Test_Missing_Vlan_Setting \ + Test_Missing_ID_UUID \ + Test_Enum_Property \ + Test_Flags_Property CERTS = \ test-ca-cert.pem \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property b/src/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property new file mode 100644 index 00000000..52b395b3 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property @@ -0,0 +1,8 @@ +[connection] +id=Test Wired Connection IP6 +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=802-3-ethernet + +[ipv6] +method=auto +ip6-privacy=2 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property b/src/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property new file mode 100644 index 00000000..3a46611d --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property @@ -0,0 +1,11 @@ +[connection] +id=Test Flags Property +uuid=05a5ec81-fa72-4b7c-9f85-4a0dfd36c84f +type=gsm + +[gsm] +number=*99# +username=username +password-flags=5 +apn=my.apn + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID b/src/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID new file mode 100644 index 00000000..138380d0 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID @@ -0,0 +1,9 @@ +# id and uuid keys are missing +# They will be auto-genetrated by NetworkManager + +[connection] +type=ethernet +autoconnect=true + +[802-3-ethernet] +mac-address=00:11:22:33:44:55 diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 new file mode 100644 index 00000000..cac135ad --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 @@ -0,0 +1,2 @@ +[connection] +type=802-3-ethernet diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 new file mode 100644 index 00000000..bbf2d8d6 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 @@ -0,0 +1 @@ +[802-3-ethernet] diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 new file mode 100644 index 00000000..d3122d53 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 @@ -0,0 +1,4 @@ +[connection] +type=802-3-ethernet +master=br0 +slave-type=bridge diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 new file mode 100644 index 00000000..eb1cdace --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 @@ -0,0 +1,7 @@ +[connection] +master=br0 + +[802-3-ethernet] + +[bridge-port] + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 new file mode 100644 index 00000000..7419e97d --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 @@ -0,0 +1,4 @@ +[connection] +master=br0 +slave-type=bridge +[802-3-ethernet] diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 new file mode 100644 index 00000000..626b6f68 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 @@ -0,0 +1,4 @@ +[connection] +type=802-3-ethernet +master=br0 +[bridge-port] diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index cc57c1c3..33e3863c 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -18,29 +18,18 @@ * Copyright (C) 2008 - 2014 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include -#include #include #include #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include "nm-core-internal.h" +#include "nm-logging.h" #include "reader.h" #include "writer.h" @@ -51,69 +40,42 @@ #define TEST_WIRELESS_FILE TEST_KEYFILES_DIR"/Test_Wireless_Connection" static void -check_ip4_address (NMSettingIP4Config *config, int idx, const char *address_str, int plen, const char *gateway_str) +check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen) { - NMIP4Address *ip4 = nm_setting_ip4_config_get_address (config, idx); - guint32 address, gateway; - - g_assert (inet_pton (AF_INET, address_str, &address) == 1); - g_assert (inet_pton (AF_INET, gateway_str, &gateway) == 1); + NMIPAddress *ip4 = nm_setting_ip_config_get_address (config, idx); g_assert (ip4); - g_assert (nm_ip4_address_get_address (ip4) == address); - g_assert (nm_ip4_address_get_prefix (ip4) == plen); - g_assert (nm_ip4_address_get_gateway (ip4) == gateway); + g_assert_cmpstr (nm_ip_address_get_address (ip4), ==, address); + g_assert_cmpint (nm_ip_address_get_prefix (ip4), ==, plen); } static void -check_ip6_address (NMSettingIP6Config *config, int idx, const char *address_str, int plen, const char *gateway_str) +check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int plen, + const char *next_hop, gint64 metric) { - NMIP6Address *ip6 = nm_setting_ip6_config_get_address (config, idx); - struct in6_addr address; - struct in6_addr gateway; + NMIPRoute *route = nm_setting_ip_config_get_route (config, idx); - g_assert (inet_pton (AF_INET6, address_str, &address) == 1); - g_assert (inet_pton (AF_INET6, gateway_str, &gateway) == 1); - - g_assert (ip6); - g_assert (!memcmp (nm_ip6_address_get_address (ip6), &address, sizeof(address))); - g_assert (nm_ip6_address_get_prefix (ip6) == plen); - g_assert (!memcmp (nm_ip6_address_get_gateway (ip6), &gateway, sizeof(gateway))); + g_assert (route); + g_assert_cmpstr (nm_ip_route_get_dest (route), ==, destination); + g_assert_cmpint (nm_ip_route_get_prefix (route), ==, plen); + g_assert_cmpstr (nm_ip_route_get_next_hop (route), ==, next_hop); + g_assert_cmpint (nm_ip_route_get_metric (route), ==, metric); } -static void -check_ip4_route (NMSettingIP4Config *config, int idx, const char *destination_str, int plen, - const char *nexthop_str, int metric) +static NMConnection * +keyfile_read_connection_from_file (const char *filename) { - NMIP4Route *route = nm_setting_ip4_config_get_route (config, idx); - guint32 destination, nexthop; + GError *error = NULL; + NMConnection *connection; - g_assert (inet_pton (AF_INET, destination_str, &destination) == 1); - g_assert (inet_pton (AF_INET, nexthop_str, &nexthop) == 1); + g_assert (filename); - g_assert (route); - g_assert (nm_ip4_route_get_dest (route) == destination); - g_assert (nm_ip4_route_get_prefix (route) == plen); - g_assert (nm_ip4_route_get_next_hop (route) == nexthop); - g_assert (nm_ip4_route_get_metric (route) == metric); -} - -static void -check_ip6_route (NMSettingIP6Config *config, int idx, const char *destination_str, int plen, - const char *next_hop_str, int metric) -{ - NMIP6Route *route = nm_setting_ip6_config_get_route (config, idx); - struct in6_addr destination; - struct in6_addr next_hop; + connection = nm_keyfile_plugin_connection_from_file (filename, &error); + g_assert_no_error (error); - g_assert (inet_pton (AF_INET6, destination_str, &destination) == 1); - g_assert (inet_pton (AF_INET6, next_hop_str, &next_hop) == 1); + nmtst_assert_connection_verifies_without_normalization (connection); - g_assert (route); - g_assert (!memcmp (nm_ip6_route_get_dest (route), &destination, sizeof(destination))); - g_assert (nm_ip6_route_get_prefix (route) == plen); - g_assert (!memcmp (nm_ip6_route_get_next_hop (route), &next_hop, sizeof(next_hop))); - g_assert (nm_ip6_route_get_metric (route) == metric); + return connection; } static void @@ -122,22 +84,16 @@ test_read_valid_wired_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; const char *tmp; const char *expected_id = "Test Wired Connection"; const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; const guint64 expected_timestamp = 6654332; guint64 timestamp; - const char *expected_dns1 = "4.2.2.1"; - const char *expected_dns2 = "4.2.2.2"; - guint32 addr; - struct in6_addr addr6; - const char *expected6_dns1 = "1111:dddd::aaaa"; - const char *expected6_dns2 = "1::cafe"; const char *expected6_dnssearch1 = "super-domain.com"; const char *expected6_dnssearch2 = "redhat.com"; const char *expected6_dnssearch3 = "gnu.org"; @@ -236,18 +192,13 @@ test_read_valid_wired_connection (void) NM_SETTING_WIRED_SETTING_NAME); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array != NULL, + mac = nm_setting_wired_get_mac_address (s_wired); + ASSERT (mac != NULL, "connection-verify-wired", "failed to verify %s: missing %s / %s key", TEST_WIRED_FILE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length", - TEST_WIRED_FILE, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_WIRED_SETTING_NAME, @@ -268,65 +219,62 @@ test_read_valid_wired_connection (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* DNS Addresses */ - ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip4) == 2, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0, - "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #1", - TEST_WIRED_FILE, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 0), "4.2.2.1") == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0, - "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_WIRED_FILE, - NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip4, 1), "4.2.2.2") == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* IPv4 addresses */ - g_assert (nm_setting_ip4_config_get_num_addresses (s_ip4) == 6); - check_ip4_address (s_ip4, 0, "2.3.4.5", 24, "2.3.4.6"); - check_ip4_address (s_ip4, 1, "192.168.0.5", 24, "192.168.0.1"); - check_ip4_address (s_ip4, 2, "1.2.3.4", 16, "1.2.1.1"); - check_ip4_address (s_ip4, 3, "3.4.5.6", 16, "0.0.0.0"); - check_ip4_address (s_ip4, 4, "4.5.6.7", 24, "1.2.3.4"); - check_ip4_address (s_ip4, 5, "5.6.7.8", 24, "0.0.0.0"); + g_assert (nm_setting_ip_config_get_num_addresses (s_ip4) == 6); + check_ip_address (s_ip4, 0, "2.3.4.5", 24); + check_ip_address (s_ip4, 1, "192.168.0.5", 24); + check_ip_address (s_ip4, 2, "1.2.3.4", 16); + check_ip_address (s_ip4, 3, "3.4.5.6", 16); + check_ip_address (s_ip4, 4, "4.5.6.7", 24); + check_ip_address (s_ip4, 5, "5.6.7.8", 24); + + /* IPv4 gateway */ + ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip4), "2.3.4.6") == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); /* IPv4 routes */ - g_assert (nm_setting_ip4_config_get_num_routes (s_ip4) == 12); - check_ip4_route (s_ip4, 0, "5.6.7.8", 32, "0.0.0.0", 0); - check_ip4_route (s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99); - check_ip4_route (s_ip4, 2, "1.1.1.2", 12, "0.0.0.0", 0); - check_ip4_route (s_ip4, 3, "1.1.1.3", 13, "0.0.0.0", 0); - check_ip4_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", 0); - check_ip4_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", 0); - check_ip4_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0); - check_ip4_route (s_ip4, 7, "1.1.1.7", 17, "0.0.0.0", 0); - check_ip4_route (s_ip4, 8, "1.1.1.8", 18, "0.0.0.0", 0); - check_ip4_route (s_ip4, 9, "1.1.1.9", 19, "0.0.0.0", 0); - check_ip4_route (s_ip4, 10, "1.1.1.10", 20, "0.0.0.0", 0); - check_ip4_route (s_ip4, 11, "1.1.1.11", 21, "0.0.0.0", 21); + g_assert (nm_setting_ip_config_get_num_routes (s_ip4) == 12); + check_ip_route (s_ip4, 0, "5.6.7.8", 32, NULL, -1); + check_ip_route (s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99); + check_ip_route (s_ip4, 2, "1.1.1.2", 12, NULL, -1); + check_ip_route (s_ip4, 3, "1.1.1.3", 13, NULL, -1); + check_ip_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", -1); + check_ip_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", -1); + check_ip_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", -1); + check_ip_route (s_ip4, 7, "1.1.1.7", 17, NULL, -1); + check_ip_route (s_ip4, 8, "1.1.1.8", 18, NULL, -1); + check_ip_route (s_ip4, 9, "1.1.1.9", 19, NULL, -1); + check_ip_route (s_ip4, 10, "1.1.1.10", 20, NULL, -1); + check_ip_route (s_ip4, 11, "1.1.1.11", 21, NULL, 21); /* ===== IPv6 SETTING ===== */ @@ -337,182 +285,118 @@ test_read_valid_wired_connection (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* DNS Addresses */ - ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2, + ASSERT (nm_setting_ip_config_get_num_dns (s_ip6) == 2, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected6_dns1, &addr6) > 0, - "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP6 address #1", - TEST_WIRED_FILE, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6), + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip6, 0), "1111:dddd::aaaa") == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); - ASSERT (inet_pton (AF_INET6, expected6_dns2, &addr6) > 0, - "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2", - TEST_WIRED_FILE, - NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); - ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6), + ASSERT (strcmp (nm_setting_ip_config_get_dns (s_ip6, 1), "1::cafe") == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* DNS Searches */ - ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 3, + ASSERT (nm_setting_ip_config_get_num_dns_searches (s_ip6) == 3, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); - ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 0), expected6_dnssearch1), + ASSERT (!strcmp (nm_setting_ip_config_get_dns_search (s_ip6, 0), expected6_dnssearch1), "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); - ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 1), expected6_dnssearch2), + NM_SETTING_IP_CONFIG_DNS_SEARCH); + ASSERT (!strcmp (nm_setting_ip_config_get_dns_search (s_ip6, 1), expected6_dnssearch2), "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); - ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 2), expected6_dnssearch3), + NM_SETTING_IP_CONFIG_DNS_SEARCH); + ASSERT (!strcmp (nm_setting_ip_config_get_dns_search (s_ip6, 2), expected6_dnssearch3), "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #3", TEST_WIRED_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS_SEARCH); + NM_SETTING_IP_CONFIG_DNS_SEARCH); /* IPv6 addresses */ - g_assert (nm_setting_ip6_config_get_num_addresses (s_ip6) == 10); - check_ip6_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64, "2:3:4:5:1:2:3:4"); - check_ip6_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64, "::"); - check_ip6_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96, "::"); - check_ip6_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128, "::"); - check_ip6_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64, "::"); - check_ip6_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64, "::"); - check_ip6_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66, "::"); - check_ip6_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67, "::"); - check_ip6_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68, "::"); - check_ip6_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69, "1::09"); + g_assert (nm_setting_ip_config_get_num_addresses (s_ip6) == 10); + check_ip_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64); + check_ip_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64); + check_ip_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96); + check_ip_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128); + check_ip_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64); + check_ip_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64); + check_ip_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66); + check_ip_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67); + check_ip_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68); + check_ip_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69); + + /* IPv6 gateway */ + ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip6), "2:3:4:5:1:2:3:4") == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); /* Route #1 */ - g_assert (nm_setting_ip6_config_get_num_routes (s_ip6) == 7); - check_ip6_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", 0); - check_ip6_route (s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99); - check_ip6_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, "::", 0); - check_ip6_route (s_ip6, 3, "6:7:8:9:0:1:2:3", 126, "::", 1); - check_ip6_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, "::", 5); - check_ip6_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, "::", 6); - check_ip6_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, "::", 0); + g_assert (nm_setting_ip_config_get_num_routes (s_ip6) == 7); + check_ip_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", -1); + check_ip_route (s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99); + check_ip_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, -1); + check_ip_route (s_ip6, 3, "6:7:8:9:0:1:2:3", 126, NULL, 1); + check_ip_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5); + check_ip_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6); + check_ip_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1); g_object_unref (connection); } static void -add_one_ip4_address (NMSettingIP4Config *s_ip4, - const char *addr, - const char *gw, - guint32 prefix) +add_one_ip_address (NMSettingIPConfig *s_ip, + const char *addr, + guint32 prefix) { - guint32 tmp; - NMIP4Address *ip4_addr; - - ip4_addr = nm_ip4_address_new (); - nm_ip4_address_set_prefix (ip4_addr, prefix); - - inet_pton (AF_INET, addr, &tmp); - nm_ip4_address_set_address (ip4_addr, tmp); - - inet_pton (AF_INET, gw, &tmp); - nm_ip4_address_set_gateway (ip4_addr, tmp); - - nm_setting_ip4_config_add_address (s_ip4, ip4_addr); - nm_ip4_address_unref (ip4_addr); -} - -static void -add_one_ip4_route (NMSettingIP4Config *s_ip4, - const char *dest, - const char *nh, - guint32 prefix, - guint32 metric) -{ - guint32 addr; - NMIP4Route *route; - - route = nm_ip4_route_new (); - nm_ip4_route_set_prefix (route, prefix); - nm_ip4_route_set_metric (route, metric); - - inet_pton (AF_INET, dest, &addr); - nm_ip4_route_set_dest (route, addr); - - inet_pton (AF_INET, nh, &addr); - nm_ip4_route_set_next_hop (route, addr); - - nm_setting_ip4_config_add_route (s_ip4, route); - nm_ip4_route_unref (route); -} - -static void -add_one_ip6_address (NMSettingIP6Config *s_ip6, - const char *addr, - guint32 prefix, - const char *gw) -{ - struct in6_addr tmp; - NMIP6Address *ip6_addr; - - ip6_addr = nm_ip6_address_new (); - nm_ip6_address_set_prefix (ip6_addr, prefix); - - inet_pton (AF_INET6, addr, &tmp); - nm_ip6_address_set_address (ip6_addr, &tmp); - - if (gw) { - inet_pton (AF_INET6, gw, &tmp); - nm_ip6_address_set_gateway (ip6_addr, &tmp); - } + NMIPAddress *ip_addr; + GError *error = NULL; - nm_setting_ip6_config_add_address (s_ip6, ip6_addr); - nm_ip6_address_unref (ip6_addr); + ip_addr = nm_ip_address_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6, + addr, prefix, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip, ip_addr); + nm_ip_address_unref (ip_addr); } static void -add_one_ip6_route (NMSettingIP6Config *s_ip6, - const char *dest, - const char *nh, - guint32 prefix, - guint32 metric) +add_one_ip_route (NMSettingIPConfig *s_ip, + const char *dest, + const char *nh, + guint32 prefix, + gint64 metric) { - struct in6_addr addr; - NMIP6Route *route; - - route = nm_ip6_route_new (); - nm_ip6_route_set_prefix (route, prefix); - nm_ip6_route_set_metric (route, metric); - - inet_pton (AF_INET6, dest, &addr); - nm_ip6_route_set_dest (route, &addr); - - inet_pton (AF_INET6, nh, &addr); - nm_ip6_route_set_next_hop (route, &addr); + NMIPRoute *route; + GError *error = NULL; - nm_setting_ip6_config_add_route (s_ip6, route); - nm_ip6_route_unref (route); + g_assert (prefix > 0); + route = nm_ip_route_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6, + dest, prefix, nh, metric, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_route (s_ip, route); + nm_ip_route_unref (route); } @@ -522,33 +406,29 @@ test_write_wired_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - GByteArray *mac; - unsigned char tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44 }; + const char *mac = "99:88:77:66:55:44"; gboolean success; NMConnection *reread; char *testfile = NULL; GError *error = NULL; pid_t owner_grp; uid_t owner_uid; - guint32 addr; - struct in6_addr addr6; const char *dns1 = "4.2.2.1"; const char *dns2 = "4.2.2.2"; const char *address1 = "192.168.0.5"; - const char *address1_gw = "192.168.0.1"; const char *address2 = "1.2.3.4"; - const char *address2_gw = "1.2.1.1"; + const char *gw = "192.168.0.1"; const char *route1 = "10.10.10.2"; const char *route1_nh = "10.10.10.1"; const char *route2 = "1.1.1.1"; const char *route2_nh = "1.2.1.1"; const char *route3 = "2.2.2.2"; - const char *route3_nh = "0.0.0.0"; + const char *route3_nh = NULL; const char *route4 = "3.3.3.3"; - const char *route4_nh = "0.0.0.0"; + const char *route4_nh = NULL; const char *dns6_1 = "1::cafe"; const char *dns6_2 = "2::cafe"; const char *address6_1 = "abcd::beef"; @@ -563,7 +443,7 @@ test_write_wired_connection (void) const char *route6_4_nh = "::"; guint64 timestamp = 0x12345678L; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -585,66 +465,60 @@ test_write_wired_connection (void) s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 900, NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, gw, NULL); /* Addresses */ - add_one_ip4_address (s_ip4, address1, address1_gw, 24); - add_one_ip4_address (s_ip4, address2, address2_gw, 8); + add_one_ip_address (s_ip4, address1, 24); + add_one_ip_address (s_ip4, address2, 8); /* Routes */ - add_one_ip4_route (s_ip4, route1, route1_nh, 24, 3); - add_one_ip4_route (s_ip4, route2, route2_nh, 8, 1); - add_one_ip4_route (s_ip4, route3, route3_nh, 7, 0); - add_one_ip4_route (s_ip4, route4, route4_nh, 6, 4); + add_one_ip_route (s_ip4, route1, route1_nh, 24, 3); + add_one_ip_route (s_ip4, route2, route2_nh, 8, 1); + add_one_ip_route (s_ip4, route3, route3_nh, 7, -1); + add_one_ip_route (s_ip4, route4, route4_nh, 6, 4); /* DNS servers */ - inet_pton (AF_INET, dns1, &addr); - nm_setting_ip4_config_add_dns (s_ip4, addr); - inet_pton (AF_INET, dns2, &addr); - nm_setting_ip4_config_add_dns (s_ip4, addr); + nm_setting_ip_config_add_dns (s_ip4, dns1); + nm_setting_ip_config_add_dns (s_ip4, dns2); /* IP6 setting */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); /* Addresses */ - add_one_ip6_address (s_ip6, address6_1, 64, NULL); - add_one_ip6_address (s_ip6, address6_2, 56, NULL); + add_one_ip_address (s_ip6, address6_1, 64); + add_one_ip_address (s_ip6, address6_2, 56); /* Routes */ - add_one_ip6_route (s_ip6, route6_1, route6_1_nh, 64, 3); - add_one_ip6_route (s_ip6, route6_2, route6_2_nh, 56, 1); - add_one_ip6_route (s_ip6, route6_3, route6_3_nh, 63, 5); - add_one_ip6_route (s_ip6, route6_4, route6_4_nh, 62, 0); + add_one_ip_route (s_ip6, route6_1, route6_1_nh, 64, 3); + add_one_ip_route (s_ip6, route6_2, route6_2_nh, 56, 1); + add_one_ip_route (s_ip6, route6_3, route6_3_nh, 63, 5); + add_one_ip_route (s_ip6, route6_4, route6_4_nh, 62, -1); /* DNS servers */ - inet_pton (AF_INET6, dns6_1, &addr6); - nm_setting_ip6_config_add_dns (s_ip6, &addr6); - inet_pton (AF_INET6, dns6_2, &addr6); - nm_setting_ip6_config_add_dns (s_ip6, &addr6); + nm_setting_ip_config_add_dns (s_ip6, dns6_1); + nm_setting_ip_config_add_dns (s_ip6, dns6_2); /* DNS searches */ - nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com"); + nm_setting_ip_config_add_dns_search (s_ip6, "wallaceandgromit.com"); /* Write out the connection */ owner_uid = geteuid (); @@ -680,8 +554,8 @@ test_read_ip6_wired_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; GError *error = NULL; const char *tmp; const char *expected_id = "Test Wired Connection IP6"; @@ -745,18 +619,18 @@ test_read_ip6_wired_connection (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_IP6_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); - ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 0, + ASSERT (nm_setting_ip_config_get_num_addresses (s_ip4) == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_IP6_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS); + NM_SETTING_IP_CONFIG_DNS); /* ===== IPv6 SETTING ===== */ @@ -767,16 +641,23 @@ test_read_ip6_wired_connection (void) NM_SETTING_IP6_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip6_config_get_method (s_ip6); + tmp = nm_setting_ip_config_get_method (s_ip6); ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_IP6_FILE, NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); /* IPv6 address */ - g_assert (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1); - check_ip6_address (s_ip6, 0, "abcd:1234:ffff::cdde", 64, "abcd:1234:ffff::cdd1"); + g_assert (nm_setting_ip_config_get_num_addresses (s_ip6) == 1); + check_ip_address (s_ip6, 0, "abcd:1234:ffff::cdde", 64); + + /* IPv6 gateway */ + ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip6), "abcd:1234:ffff::cdd1") == 0, + "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", + TEST_WIRED_IP6_FILE, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_GATEWAY); g_object_unref (connection); } @@ -787,8 +668,8 @@ test_write_ip6_wired_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; NMConnection *reread; @@ -796,12 +677,11 @@ test_write_ip6_wired_connection (void) GError *error = NULL; pid_t owner_grp; uid_t owner_uid; - struct in6_addr addr6; const char *dns = "1::cafe"; const char *address = "abcd::beef"; const char *gw = "dcba::beef"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -824,31 +704,31 @@ test_write_ip6_wired_connection (void) /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); /* IP6 setting */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, gw, NULL); /* Addresses */ - add_one_ip6_address (s_ip6, address, 64, gw); + add_one_ip_address (s_ip6, address, 64); /* DNS servers */ - inet_pton (AF_INET6, dns, &addr6); - nm_setting_ip6_config_add_dns (s_ip6, &addr6); + nm_setting_ip_config_add_dns (s_ip6, dns); /* DNS searches */ - nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com"); + nm_setting_ip_config_add_dns_search (s_ip6, "wallaceandgromit.com"); /* Write out the connection */ owner_uid = geteuid (); @@ -885,7 +765,7 @@ test_read_wired_mac_case (void) NMSettingConnection *s_con; NMSettingWired *s_wired; GError *error = NULL; - const GByteArray *array; + const char *mac; char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; const char *tmp; const char *expected_id = "Test Wired Connection MAC Case"; @@ -948,18 +828,13 @@ test_read_wired_mac_case (void) NM_SETTING_WIRED_SETTING_NAME); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - ASSERT (array != NULL, + mac = nm_setting_wired_get_mac_address (s_wired); + ASSERT (mac != NULL, "connection-verify-wired", "failed to verify %s: missing %s / %s key", TEST_WIRED_MAC_CASE_FILE, NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (array->len == ETH_ALEN, - "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length", - TEST_WIRED_MAC_CASE_FILE, - NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS); - ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0, + ASSERT (nm_utils_hwaddr_matches (mac, -1, expected_mac_address, sizeof (expected_mac_address)), "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value", TEST_WIRED_MAC_CASE_FILE, NM_SETTING_WIRED_SETTING_NAME, @@ -977,7 +852,7 @@ test_read_mac_old_format (void) NMSettingWired *s_wired; GError *error = NULL; gboolean success; - const GByteArray *array; + const char *mac; char expected_mac[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; char expected_cloned_mac[ETH_ALEN] = { 0x00, 0x16, 0xaa, 0xbb, 0xcc, 0xfe }; @@ -993,16 +868,14 @@ test_read_mac_old_format (void) g_assert (s_wired); /* MAC address */ - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, expected_mac, ETH_ALEN) == 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, ETH_ALEN)); /* Cloned MAC address */ - array = nm_setting_wired_get_cloned_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert (memcmp (array->data, expected_cloned_mac, ETH_ALEN) == 0); + mac = nm_setting_wired_get_cloned_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_cloned_mac, ETH_ALEN)); g_object_unref (connection); } @@ -1016,7 +889,7 @@ test_read_mac_ib_old_format (void) NMSettingInfiniband *s_ib; GError *error = NULL; gboolean success; - const GByteArray *array; + const char *mac; guint8 expected_mac[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90 }; @@ -1033,10 +906,9 @@ test_read_mac_ib_old_format (void) g_assert (s_ib); /* MAC address */ - array = nm_setting_infiniband_get_mac_address (s_ib); - g_assert (array); - g_assert_cmpint (array->len, ==, INFINIBAND_ALEN); - g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + mac = nm_setting_infiniband_get_mac_address (s_ib); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); g_object_unref (connection); } @@ -1047,10 +919,10 @@ test_read_valid_wireless_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; GError *error = NULL; - const GByteArray *array; - char expected_bssid[ETH_ALEN] = { 0x00, 0x1a, 0x33, 0x44, 0x99, 0x82 }; + const char *bssid; + const guint8 expected_bssid[ETH_ALEN] = { 0x00, 0x1a, 0x33, 0x44, 0x99, 0x82 }; const char *tmp; const char *expected_id = "Test Wireless Connection"; const char *expected_uuid = "2f962388-e5f3-45af-a62c-ac220b8f7baa"; @@ -1122,18 +994,13 @@ test_read_valid_wireless_connection (void) NM_SETTING_WIRED_SETTING_NAME); /* BSSID */ - array = nm_setting_wireless_get_bssid (s_wireless); - ASSERT (array != NULL, + bssid = nm_setting_wireless_get_bssid (s_wireless); + ASSERT (bssid != NULL, "connection-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_WIRELESS_FILE, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BSSID); - ASSERT (array->len == ETH_ALEN, - "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value length", - TEST_WIRELESS_FILE, - NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_BSSID); - ASSERT (memcmp (array->data, &expected_bssid[0], sizeof (expected_bssid)) == 0, + ASSERT (nm_utils_hwaddr_matches (bssid, -1, expected_bssid, sizeof (expected_bssid)), "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_WIRELESS_FILE, NM_SETTING_WIRELESS_SETTING_NAME, @@ -1148,12 +1015,12 @@ test_read_valid_wireless_connection (void) NM_SETTING_IP4_CONFIG_SETTING_NAME); /* Method */ - tmp = nm_setting_ip4_config_get_method (s_ip4); + tmp = nm_setting_ip_config_get_method (s_ip4); ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value", TEST_WIRELESS_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_METHOD); + NM_SETTING_IP_CONFIG_METHOD); g_object_unref (connection); } @@ -1164,12 +1031,11 @@ test_write_wireless_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - GByteArray *bssid; - unsigned char tmpbssid[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 }; - GByteArray *ssid; + const char *bssid = "aa:b9:a1:74:55:44"; + GBytes *ssid; unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; gboolean success; NMConnection *reread; @@ -1179,7 +1045,7 @@ test_write_wireless_connection (void) uid_t owner_uid; guint64 timestamp = 0x12344433L; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -1201,11 +1067,7 @@ test_write_wireless_connection (void) s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); nm_connection_add_setting (connection, NM_SETTING (s_wireless)); - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, &tmpbssid[0], sizeof (tmpbssid)); - - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, @@ -1213,25 +1075,24 @@ test_write_wireless_connection (void) NM_SETTING_WIRED_MTU, 1000, NULL); - g_byte_array_free (bssid, TRUE); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ @@ -1268,7 +1129,9 @@ test_read_string_ssid (void) NMConnection *connection; NMSettingWireless *s_wireless; GError *error = NULL; - const GByteArray *array; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "blah blah ssid 1234"; connection = nm_keyfile_plugin_connection_from_file (TEST_STRING_SSID_FILE, NULL); @@ -1287,14 +1150,15 @@ test_read_string_ssid (void) NM_SETTING_WIRELESS_SETTING_NAME); /* SSID */ - array = nm_setting_wireless_get_ssid (s_wireless); - ASSERT (array != NULL, + ssid = nm_setting_wireless_get_ssid (s_wireless); + ASSERT (ssid != NULL, "connection-verify-wireless", "failed to verify %s: missing %s / %s key", TEST_STRING_SSID_FILE, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); - g_assert_cmpint (array->len, ==, strlen (expected_ssid)); - g_assert (memcmp (array->data, expected_ssid, array->len) == 0); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert (memcmp (ssid_data, expected_ssid, ssid_len) == 0); g_object_unref (connection); } @@ -1305,9 +1169,9 @@ test_write_string_ssid (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid, *testfile = NULL, *tmp; - GByteArray *ssid; + GBytes *ssid; unsigned char tmpssid[] = { 65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93 }; gboolean success; NMConnection *reread; @@ -1316,7 +1180,7 @@ test_write_string_ssid (void) uid_t owner_uid; GKeyFile *keyfile; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -1336,18 +1200,17 @@ test_write_string_ssid (void) s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); nm_connection_add_setting (connection, NM_SETTING (s_wireless)); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ @@ -1378,8 +1241,7 @@ test_write_string_ssid (void) reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); - ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, - "connection-write", "written and re-read connection weren't the same"); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -1398,7 +1260,9 @@ test_read_intlist_ssid (void) NMSettingWireless *s_wifi; GError *error = NULL; gboolean success; - const GByteArray *array; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "blah1234"; connection = nm_keyfile_plugin_connection_from_file (TEST_INTLIST_SSID_FILE, &error); @@ -1413,10 +1277,11 @@ test_read_intlist_ssid (void) s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - array = nm_setting_wireless_get_ssid (s_wifi); - g_assert (array != NULL); - g_assert_cmpint (array->len, ==, strlen (expected_ssid)); - g_assert_cmpint (memcmp (array->data, expected_ssid, strlen (expected_ssid)), ==, 0); + ssid = nm_setting_wireless_get_ssid (s_wifi); + g_assert (ssid != NULL); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, strlen (expected_ssid)), ==, 0); g_object_unref (connection); } @@ -1427,9 +1292,9 @@ test_write_intlist_ssid (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid, *testfile = NULL; - GByteArray *ssid; + GBytes *ssid; unsigned char tmpssid[] = { 65, 49, 50, 51, 0, 50, 50 }; gboolean success; NMConnection *reread; @@ -1440,7 +1305,7 @@ test_write_intlist_ssid (void) gint *intlist; gsize len = 0, i; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -1462,16 +1327,15 @@ test_write_intlist_ssid (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ owner_uid = geteuid (); @@ -1503,8 +1367,7 @@ test_write_intlist_ssid (void) g_assert_no_error (error); g_assert (reread); - success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); - g_assert (success); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -1523,7 +1386,9 @@ test_read_intlike_ssid (void) NMSettingWireless *s_wifi; GError *error = NULL; gboolean success; - const GByteArray *array; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "101"; connection = nm_keyfile_plugin_connection_from_file (TEST_INTLIKE_SSID_FILE, &error); @@ -1538,10 +1403,11 @@ test_read_intlike_ssid (void) s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - array = nm_setting_wireless_get_ssid (s_wifi); - g_assert (array != NULL); - g_assert_cmpint (array->len, ==, strlen (expected_ssid)); - g_assert_cmpint (memcmp (array->data, expected_ssid, strlen (expected_ssid)), ==, 0); + ssid = nm_setting_wireless_get_ssid (s_wifi); + g_assert (ssid != NULL); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, strlen (expected_ssid)), ==, 0); g_object_unref (connection); } @@ -1555,7 +1421,9 @@ test_read_intlike_ssid_2 (void) NMSettingWireless *s_wifi; GError *error = NULL; gboolean success; - const GByteArray *array; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "11;12;13;"; connection = nm_keyfile_plugin_connection_from_file (TEST_INTLIKE_SSID_2_FILE, &error); @@ -1570,10 +1438,11 @@ test_read_intlike_ssid_2 (void) s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - array = nm_setting_wireless_get_ssid (s_wifi); - g_assert (array != NULL); - g_assert_cmpint (array->len, ==, strlen (expected_ssid)); - g_assert_cmpint (memcmp (array->data, expected_ssid, strlen (expected_ssid)), ==, 0); + ssid = nm_setting_wireless_get_ssid (s_wifi); + g_assert (ssid != NULL); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, strlen (expected_ssid)), ==, 0); g_object_unref (connection); } @@ -1584,9 +1453,9 @@ test_write_intlike_ssid (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid, *testfile = NULL; - GByteArray *ssid; + GBytes *ssid; unsigned char tmpssid[] = { 49, 48, 49 }; gboolean success; NMConnection *reread; @@ -1596,7 +1465,7 @@ test_write_intlike_ssid (void) GKeyFile *keyfile; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -1618,16 +1487,15 @@ test_write_intlike_ssid (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ owner_uid = geteuid (); @@ -1655,8 +1523,7 @@ test_write_intlike_ssid (void) g_assert_no_error (error); g_assert (reread); - success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); - g_assert (success); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -1672,9 +1539,9 @@ test_write_intlike_ssid_2 (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; char *uuid, *testfile = NULL; - GByteArray *ssid; + GBytes *ssid; unsigned char tmpssid[] = { 49, 49, 59, 49, 50, 59, 49, 51, 59}; gboolean success; NMConnection *reread; @@ -1684,7 +1551,7 @@ test_write_intlike_ssid_2 (void) GKeyFile *keyfile; char *tmp; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -1706,16 +1573,15 @@ test_write_intlike_ssid_2 (void) g_assert (s_wifi); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ owner_uid = geteuid (); @@ -1743,8 +1609,7 @@ test_write_intlike_ssid_2 (void) g_assert_no_error (error); g_assert (reread); - success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); - g_assert (success); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -1765,9 +1630,10 @@ test_read_bt_dun_connection (void) NMSettingSerial *s_serial; NMSettingGsm *s_gsm; GError *error = NULL; - const GByteArray *array; - char expected_bdaddr[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + const char *bdaddr; + const guint8 expected_bdaddr[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; const char *tmp; + NMSettingSerialParity parity; const char *expected_id = "AT&T Data Connect BT"; const char *expected_uuid = "089130ab-ce28-46e4-ad77-d44869b03d19"; const char *expected_apn = "ISP.CINGULAR"; @@ -1824,18 +1690,13 @@ test_read_bt_dun_connection (void) NM_SETTING_WIRED_SETTING_NAME); /* BDADDR */ - array = nm_setting_bluetooth_get_bdaddr (s_bluetooth); - ASSERT (array != NULL, + bdaddr = nm_setting_bluetooth_get_bdaddr (s_bluetooth); + ASSERT (bdaddr != NULL, "connection-verify-bt", "failed to verify %s: missing %s / %s key", TEST_BT_DUN_FILE, NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); - ASSERT (array->len == ETH_ALEN, - "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value length", - TEST_BT_DUN_FILE, - NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_SETTING_BLUETOOTH_BDADDR); - ASSERT (memcmp (array->data, &expected_bdaddr[0], sizeof (expected_bdaddr)) == 0, + ASSERT (nm_utils_hwaddr_matches (bdaddr, -1, expected_bdaddr, sizeof (expected_bdaddr)), "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value", TEST_BT_DUN_FILE, NM_SETTING_BLUETOOTH_SETTING_NAME, @@ -1909,6 +1770,13 @@ test_read_bt_dun_connection (void) TEST_BT_DUN_FILE, NM_SETTING_SERIAL_SETTING_NAME); + parity = nm_setting_serial_get_parity (s_serial); + ASSERT (parity == NM_SETTING_SERIAL_PARITY_ODD, + "connection-verify-serial", "failed to verify %s: unexpected %s / %s key value", + TEST_BT_DUN_FILE, + NM_SETTING_SERIAL_SETTING_NAME, + NM_SETTING_SERIAL_PARITY); + g_object_unref (connection); } @@ -1918,11 +1786,10 @@ test_write_bt_dun_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingBluetooth *s_bt; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSettingGsm *s_gsm; char *uuid; - GByteArray *bdaddr; - unsigned char tmpbdaddr[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 }; + const char *bdaddr = "aa:b9:a1:74:55:44"; gboolean success; NMConnection *reread; char *testfile = NULL; @@ -1931,7 +1798,7 @@ test_write_bt_dun_connection (void) uid_t owner_uid; guint64 timestamp = 0x12344433L; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -1953,23 +1820,18 @@ test_write_bt_dun_connection (void) s_bt = NM_SETTING_BLUETOOTH (nm_setting_bluetooth_new ()); nm_connection_add_setting (connection, NM_SETTING (s_bt)); - bdaddr = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bdaddr, &tmpbdaddr[0], sizeof (tmpbdaddr)); - g_object_set (s_bt, NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN, NULL); - g_byte_array_free (bdaddr, TRUE); - /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* GSM setting */ @@ -1998,8 +1860,7 @@ test_write_bt_dun_connection (void) reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); - ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, - "connection-write", "written and re-read connection weren't the same"); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -2021,6 +1882,7 @@ test_read_gsm_connection (void) NMSettingBluetooth *s_bluetooth; GError *error = NULL; const char *tmp; + NMSettingSerialParity parity; const char *expected_id = "AT&T Data Connect"; const char *expected_apn = "ISP.CINGULAR"; const char *expected_username = "ISP@CINGULARGPRS.COM"; @@ -2158,6 +2020,13 @@ test_read_gsm_connection (void) TEST_GSM_FILE, NM_SETTING_SERIAL_SETTING_NAME); + parity = nm_setting_serial_get_parity (s_serial); + ASSERT (parity == NM_SETTING_SERIAL_PARITY_ODD, + "connection-verify-serial", "failed to verify %s: unexpected %s / %s key value", + TEST_GSM_FILE, + NM_SETTING_SERIAL_SETTING_NAME, + NM_SETTING_SERIAL_PARITY); + g_object_unref (connection); } @@ -2166,7 +2035,7 @@ test_write_gsm_connection (void) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSettingGsm *s_gsm; char *uuid; gboolean success; @@ -2177,7 +2046,7 @@ test_write_gsm_connection (void) uid_t owner_uid; guint64 timestamp = 0x12344433L; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -2196,11 +2065,11 @@ test_write_gsm_connection (void) /* IP4 setting */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); + s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* GSM setting */ @@ -2215,7 +2084,6 @@ test_write_gsm_connection (void) NM_SETTING_GSM_PIN, "123456", NM_SETTING_GSM_NETWORK_ID, "254098", NM_SETTING_GSM_HOME_ONLY, TRUE, - NM_SETTING_GSM_NETWORK_TYPE, NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA, NULL); /* Write out the connection */ @@ -2233,8 +2101,7 @@ test_write_gsm_connection (void) reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); - ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, - "connection-write", "written and re-read connection weren't the same"); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); g_clear_error (&error); unlink (testfile); @@ -2255,7 +2122,7 @@ test_read_wired_8021x_tls_blob_connection (void) GError *error = NULL; const char *tmp; gboolean success; - const GByteArray *array; + GBytes *blob; connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_BLOB_FILE, &error); if (connection == NULL) { @@ -2292,16 +2159,16 @@ test_read_wired_8021x_tls_blob_connection (void) g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_BLOB); /* Make sure it's not a path, since it's a blob */ - g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, + g_test_expect_message ("libnm", G_LOG_LEVEL_CRITICAL, "*assertion*scheme == NM_SETTING_802_1X_CK_SCHEME_PATH*"); tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); g_test_assert_expected_messages (); g_assert (tmp == NULL); /* Validate the path */ - array = nm_setting_802_1x_get_ca_cert_blob (s_8021x); - g_assert (array != NULL); - g_assert_cmpint (array->len, ==, 568); + blob = nm_setting_802_1x_get_ca_cert_blob (s_8021x); + g_assert (blob != NULL); + g_assert_cmpint (g_bytes_get_size (blob), ==, 568); tmp = nm_setting_802_1x_get_client_cert_path (s_8021x); g_assert_cmpstr (tmp, ==, "/home/dcbw/Desktop/certinfra/client.pem"); @@ -2504,14 +2371,14 @@ create_wired_tls_connection (NMSetting8021xCKScheme scheme) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSetting *s_wired; NMSetting8021x *s_8021x; char *uuid; gboolean success; GError *error = NULL; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection != NULL); /* Connection setting */ @@ -2528,9 +2395,9 @@ create_wired_tls_connection (NMSetting8021xCKScheme scheme) g_free (uuid); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); /* Wired setting */ @@ -2769,7 +2636,7 @@ test_read_infiniband_connection (void) NMSettingConnection *s_con; NMSettingInfiniband *s_ib; GError *error = NULL; - const GByteArray *array; + const char *mac; guint8 expected_mac[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90 }; @@ -2794,10 +2661,9 @@ test_read_infiniband_connection (void) s_ib = nm_connection_get_setting_infiniband (connection); g_assert (s_ib); - array = nm_setting_infiniband_get_mac_address (s_ib); - g_assert (array); - g_assert_cmpint (array->len, ==, INFINIBAND_ALEN); - g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + mac = nm_setting_infiniband_get_mac_address (s_ib); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); g_object_unref (connection); } @@ -2808,13 +2674,10 @@ test_write_infiniband_connection (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingInfiniband *s_ib; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; - GByteArray *mac; - guint8 tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0xab, 0xbc, - 0xcd, 0xde, 0xef, 0xf0, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f, 0x6f, 0xba - }; + const char *mac = "99:88:77:66:55:44:ab:bc:cd:de:ef:f0:0a:1b:2c:3d:4e:5f:6f:ba"; gboolean success; NMConnection *reread; char *testfile = NULL; @@ -2822,7 +2685,7 @@ test_write_infiniband_connection (void) pid_t owner_grp; uid_t owner_uid; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -2845,26 +2708,23 @@ test_write_infiniband_connection (void) g_assert (s_ib); nm_connection_add_setting (connection, NM_SETTING (s_ib)); - mac = g_byte_array_sized_new (sizeof (tmpmac)); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); g_object_set (s_ib, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NM_SETTING_INFINIBAND_MTU, 900, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram", NULL); - g_byte_array_free (mac, TRUE); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ owner_uid = geteuid (); @@ -2895,7 +2755,7 @@ test_read_bridge_main (void) { NMConnection *connection; NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSettingBridge *s_bridge; GError *error = NULL; const char *expected_id = "Test Bridge Main"; @@ -2914,16 +2774,16 @@ test_read_bridge_main (void) g_assert (s_con); g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id); g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, expected_uuid); + g_assert_cmpstr (nm_setting_connection_get_interface_name (s_con), ==, "br0"); /* IPv4 setting */ s_ip4 = nm_connection_get_setting_ip4_config (connection); g_assert (s_ip4); - g_assert_cmpstr (nm_setting_ip4_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); + g_assert_cmpstr (nm_setting_ip_config_get_method (s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO); /* Bridge setting */ s_bridge = nm_connection_get_setting_bridge (connection); g_assert (s_bridge); - g_assert_cmpstr (nm_setting_bridge_get_interface_name (s_bridge), ==, "br0"); g_assert_cmpuint (nm_setting_bridge_get_forward_delay (s_bridge), ==, 0); g_assert_cmpuint (nm_setting_bridge_get_stp (s_bridge), ==, TRUE); g_assert_cmpuint (nm_setting_bridge_get_priority (s_bridge), ==, 32744); @@ -2940,8 +2800,8 @@ test_write_bridge_main (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingBridge *s_bridge; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; char *uuid; gboolean success; NMConnection *reread; @@ -2950,7 +2810,7 @@ test_write_bridge_main (void) pid_t owner_grp; uid_t owner_uid; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -2973,26 +2833,23 @@ test_write_bridge_main (void) g_assert (s_bridge); nm_connection_add_setting (connection, NM_SETTING (s_bridge)); - g_object_set (s_bridge, - NM_SETTING_BRIDGE_INTERFACE_NAME, "br0", - NULL); - /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); g_assert (s_ip4); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", NULL); - add_one_ip4_address (s_ip4, "1.2.3.4", "1.1.1.1", 24); + add_one_ip_address (s_ip4, "1.2.3.4", 24); /* IP6 setting */ - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); g_assert (s_ip6); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); /* Write out the connection */ owner_uid = geteuid (); @@ -3025,7 +2882,7 @@ test_read_bridge_component (void) NMSettingConnection *s_con; NMSettingBridgePort *s_port; NMSettingWired *s_wired; - const GByteArray *array; + const char *mac; guint8 expected_mac[ETH_ALEN] = { 0x00, 0x22, 0x15, 0x59, 0x62, 0x97 }; GError *error = NULL; const char *expected_id = "Test Bridge Component"; @@ -3050,10 +2907,9 @@ test_read_bridge_component (void) /* Wired setting */ s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired); - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); /* BridgePort setting */ s_port = nm_connection_get_setting_bridge_port (connection); @@ -3073,8 +2929,7 @@ test_write_bridge_component (void) NMSettingBridgePort *s_port; NMSettingWired *s_wired; char *uuid; - GByteArray *mac; - guint8 tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44 }; + const char *mac = "99:88:77:66:55:44"; gboolean success; NMConnection *reread; char *testfile = NULL; @@ -3082,7 +2937,7 @@ test_write_bridge_component (void) pid_t owner_grp; uid_t owner_uid; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -3106,13 +2961,10 @@ test_write_bridge_component (void) g_assert (s_wired); nm_connection_add_setting (connection, NM_SETTING (s_wired)); - mac = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac)); g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 1300, NULL); - g_byte_array_free (mac, TRUE); /* BridgePort setting */ s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new (); @@ -3151,7 +3003,7 @@ test_read_new_wired_group_name (void) { NMConnection *connection; NMSettingWired *s_wired; - const GByteArray *array; + const char *mac; guint8 expected_mac[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; GError *error = NULL; gboolean success; @@ -3168,10 +3020,9 @@ test_read_new_wired_group_name (void) g_assert (s_wired); g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1400); - array = nm_setting_wired_get_mac_address (s_wired); - g_assert (array); - g_assert_cmpint (array->len, ==, ETH_ALEN); - g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + mac = nm_setting_wired_get_mac_address (s_wired); + g_assert (mac); + g_assert (nm_utils_hwaddr_matches (mac, -1, expected_mac, sizeof (expected_mac))); g_object_unref (connection); } @@ -3193,7 +3044,7 @@ test_write_new_wired_group_name (void) char *s; gint mtu; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); g_assert (connection); /* Connection setting */ @@ -3227,7 +3078,7 @@ test_write_new_wired_group_name (void) reread = nm_keyfile_plugin_connection_from_file (testfile, &error); g_assert_no_error (error); g_assert (reread); - g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); /* Look at the keyfile itself to ensure we wrote out the new group names and type */ kf = g_key_file_new (); @@ -3257,7 +3108,9 @@ test_read_new_wireless_group_names (void) NMConnection *connection; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - const GByteArray *array; + GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "foobar"; GError *error = NULL; gboolean success; @@ -3273,10 +3126,11 @@ test_read_new_wireless_group_names (void) s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); - array = nm_setting_wireless_get_ssid (s_wifi); - g_assert (array); - g_assert_cmpint (array->len, ==, strlen (expected_ssid)); - g_assert_cmpint (memcmp (array->data, expected_ssid, array->len), ==, 0); + ssid = nm_setting_wireless_get_ssid (s_wifi); + g_assert (ssid); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, ssid_len), ==, 0); g_assert_cmpstr (nm_setting_wireless_get_mode (s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA); @@ -3297,7 +3151,7 @@ test_write_new_wireless_group_names (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; char *uuid; - GByteArray *ssid; + GBytes *ssid; unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; const char *expected_psk = "asdfasdfasdfa12315"; gboolean success; @@ -3309,7 +3163,7 @@ test_write_new_wireless_group_names (void) GKeyFile *kf; char *s; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ @@ -3328,13 +3182,12 @@ test_write_new_wireless_group_names (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (tmpssid)); - g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + ssid = g_bytes_new (tmpssid, sizeof (tmpssid)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, NULL); - g_byte_array_free (ssid, TRUE); + g_bytes_unref (ssid); /* WiFi security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -3357,7 +3210,7 @@ test_write_new_wireless_group_names (void) reread = nm_keyfile_plugin_connection_from_file (testfile, &error); g_assert_no_error (error); g_assert (reread); - g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); /* Look at the keyfile itself to ensure we wrote out the new group names and type */ kf = g_key_file_new (); @@ -3410,72 +3263,357 @@ test_read_missing_vlan_setting (void) g_object_unref (connection); } +static void +test_read_missing_id_uuid (void) +{ + NMConnection *connection; + GError *error = NULL; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_KEYFILES_DIR"/Test_Missing_ID_UUID", &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Ensure the ID and UUID properties are there */ + g_assert_cmpstr (nm_connection_get_id (connection), ==, "Test_Missing_ID_UUID"); + g_assert (nm_connection_get_uuid (connection)); + + g_object_unref (connection); +} + +static void +test_read_minimal (void) +{ + NMConnection *connection = NULL; + gs_unref_object NMConnection *con_archetype = NULL; + NMSettingConnection *s_con; + + con_archetype = nmtst_create_minimal_connection ("Test_minimal_x", + "a15bd68f-c32b-40b8-8d27-49e472a85919", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + nmtst_connection_normalize (con_archetype); + + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_1"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); + + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_2"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); +} + +static void +test_read_minimal_slave (void) +{ + NMConnection *connection = NULL; + gs_unref_object NMConnection *con_archetype = NULL; + NMSettingConnection *s_con; + + con_archetype = nmtst_create_minimal_connection ("Test_minimal_slave_x", + "a56b4ca5-7075-43d4-82c7-5d0cb15f7654", + NM_SETTING_WIRED_SETTING_NAME, + &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_MASTER, "br0", + NM_SETTING_CONNECTION_SLAVE_TYPE, "bridge", + NULL); + nmtst_connection_normalize (con_archetype); + + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_1"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); + + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_2"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_3"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); + + connection = keyfile_read_connection_from_file (TEST_KEYFILES_DIR"/Test_minimal_slave_4"); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, nm_connection_get_id (connection), + NM_SETTING_CONNECTION_UUID, nm_connection_get_uuid (connection), + NULL); + nmtst_assert_connection_equals (con_archetype, FALSE, connection, FALSE); + g_clear_object (&connection); +} + +static void +test_read_enum_property (void) +{ + NMConnection *connection; + NMSettingIPConfig *s_ip6; + GError *error = NULL; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_KEYFILES_DIR"/Test_Enum_Property", &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* IPv6 setting */ + s_ip6 = nm_connection_get_setting_ip6_config (connection); + g_assert (s_ip6); + g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); + + g_object_unref (connection); +} + +static void +test_write_enum_property (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIPConfig *s_ip6; + char *uuid; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Enum Property", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP6 setting */ + s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NULL); + + nmtst_connection_normalize (connection); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + + nmtst_assert_connection_equals (reread, FALSE, connection, FALSE); + + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +static void +test_read_flags_property (void) +{ + NMConnection *connection; + NMSettingGsm *s_gsm; + GError *error = NULL; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_KEYFILES_DIR"/Test_Flags_Property", &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* GSM setting */ + s_gsm = nm_connection_get_setting_gsm (connection); + g_assert (s_gsm); + g_assert_cmpint (nm_setting_gsm_get_password_flags (s_gsm), ==, + NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); + + g_object_unref (connection); +} + +static void +test_write_flags_property (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSetting *s_gsm; + char *uuid; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + + connection = nm_simple_connection_new (); + + /* Connection setting */ + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Flags Property", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME, + NULL); + g_free (uuid); + + /* GSM setting */ + s_gsm = nm_setting_gsm_new (); + nm_connection_add_setting (connection, s_gsm); + g_object_set (s_gsm, + NM_SETTING_GSM_NUMBER, "#99*", + NM_SETTING_GSM_APN, "myapn", + NM_SETTING_GSM_USERNAME, "adfasdfasdf", + NM_SETTING_GSM_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED, + NULL); + + nmtst_connection_normalize (connection); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + + nmtst_assert_connection_equals (reread, FALSE, connection, FALSE); + + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + NMTST_DEFINE (); int main (int argc, char **argv) { - char *base; - nmtst_init_assert_logging (&argc, &argv); /* The tests */ - test_read_valid_wired_connection (); - test_write_wired_connection (); + g_test_add_func ("/keyfile/test_read_valid_wired_connection ", test_read_valid_wired_connection); + g_test_add_func ("/keyfile/test_write_wired_connection ", test_write_wired_connection); + + g_test_add_func ("/keyfile/test_read_ip6_wired_connection ", test_read_ip6_wired_connection); + g_test_add_func ("/keyfile/test_write_ip6_wired_connection ", test_write_ip6_wired_connection); + + g_test_add_func ("/keyfile/test_read_wired_mac_case ", test_read_wired_mac_case); + g_test_add_func ("/keyfile/test_read_mac_old_format ", test_read_mac_old_format); + g_test_add_func ("/keyfile/test_read_mac_ib_old_format ", test_read_mac_ib_old_format); - test_read_ip6_wired_connection (); - test_write_ip6_wired_connection (); + g_test_add_func ("/keyfile/test_read_valid_wireless_connection ", test_read_valid_wireless_connection); + g_test_add_func ("/keyfile/test_write_wireless_connection ", test_write_wireless_connection); - test_read_wired_mac_case (); - test_read_mac_old_format (); - test_read_mac_ib_old_format (); + g_test_add_func ("/keyfile/test_read_string_ssid ", test_read_string_ssid); + g_test_add_func ("/keyfile/test_write_string_ssid ", test_write_string_ssid); - test_read_valid_wireless_connection (); - test_write_wireless_connection (); + g_test_add_func ("/keyfile/test_read_intlist_ssid ", test_read_intlist_ssid); + g_test_add_func ("/keyfile/test_write_intlist_ssid ", test_write_intlist_ssid); - test_read_string_ssid (); - test_write_string_ssid (); + g_test_add_func ("/keyfile/test_read_intlike_ssid ", test_read_intlike_ssid); + g_test_add_func ("/keyfile/test_write_intlike_ssid ", test_write_intlike_ssid); - test_read_intlist_ssid (); - test_write_intlist_ssid (); + g_test_add_func ("/keyfile/test_read_intlike_ssid_2 ", test_read_intlike_ssid_2); + g_test_add_func ("/keyfile/test_write_intlike_ssid_2 ", test_write_intlike_ssid_2); - test_read_intlike_ssid (); - test_write_intlike_ssid (); + g_test_add_func ("/keyfile/test_read_bt_dun_connection ", test_read_bt_dun_connection); + g_test_add_func ("/keyfile/test_write_bt_dun_connection ", test_write_bt_dun_connection); - test_read_intlike_ssid_2 (); - test_write_intlike_ssid_2 (); + g_test_add_func ("/keyfile/test_read_gsm_connection ", test_read_gsm_connection); + g_test_add_func ("/keyfile/test_write_gsm_connection ", test_write_gsm_connection); - test_read_bt_dun_connection (); - test_write_bt_dun_connection (); + g_test_add_func ("/keyfile/test_read_wired_8021x_tls_blob_connection ", test_read_wired_8021x_tls_blob_connection); + g_test_add_func ("/keyfile/test_read_wired_8021x_tls_bad_path_connection ", test_read_wired_8021x_tls_bad_path_connection); - test_read_gsm_connection (); - test_write_gsm_connection (); + g_test_add_func ("/keyfile/test_read_wired_8021x_tls_old_connection ", test_read_wired_8021x_tls_old_connection); + g_test_add_func ("/keyfile/test_read_wired_8021x_tls_new_connection ", test_read_wired_8021x_tls_new_connection); + g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_path ", test_write_wired_8021x_tls_connection_path); + g_test_add_func ("/keyfile/test_write_wired_8021x_tls_connection_blob ", test_write_wired_8021x_tls_connection_blob); - test_read_wired_8021x_tls_blob_connection (); - test_read_wired_8021x_tls_bad_path_connection (); + g_test_add_func ("/keyfile/test_read_infiniband_connection ", test_read_infiniband_connection); + g_test_add_func ("/keyfile/test_write_infiniband_connection ", test_write_infiniband_connection); - test_read_wired_8021x_tls_old_connection (); - test_read_wired_8021x_tls_new_connection (); - test_write_wired_8021x_tls_connection_path (); - test_write_wired_8021x_tls_connection_blob (); + g_test_add_func ("/keyfile/test_read_bridge_main ", test_read_bridge_main); + g_test_add_func ("/keyfile/test_write_bridge_main ", test_write_bridge_main); + g_test_add_func ("/keyfile/test_read_bridge_component ", test_read_bridge_component); + g_test_add_func ("/keyfile/test_write_bridge_component ", test_write_bridge_component); - test_read_infiniband_connection (); - test_write_infiniband_connection (); + g_test_add_func ("/keyfile/test_read_new_wired_group_name ", test_read_new_wired_group_name); + g_test_add_func ("/keyfile/test_write_new_wired_group_name ", test_write_new_wired_group_name); + g_test_add_func ("/keyfile/test_read_new_wireless_group_names ", test_read_new_wireless_group_names); + g_test_add_func ("/keyfile/test_write_new_wireless_group_names ", test_write_new_wireless_group_names); - test_read_bridge_main (); - test_write_bridge_main (); - test_read_bridge_component (); - test_write_bridge_component (); + g_test_add_func ("/keyfile/test_read_missing_vlan_setting ", test_read_missing_vlan_setting); + g_test_add_func ("/keyfile/test_read_missing_id_uuid ", test_read_missing_id_uuid); - test_read_new_wired_group_name (); - test_write_new_wired_group_name (); - test_read_new_wireless_group_names (); - test_write_new_wireless_group_names (); + g_test_add_func ("/keyfile/test_read_minimal", test_read_minimal); + g_test_add_func ("/keyfile/test_read_minimal_slave", test_read_minimal_slave); - test_read_missing_vlan_setting (); + g_test_add_func ("/keyfile/test_read_enum_property ", test_read_enum_property); + g_test_add_func ("/keyfile/test_write_enum_property ", test_write_enum_property); + g_test_add_func ("/keyfile/test_read_flags_property ", test_read_flags_property); + g_test_add_func ("/keyfile/test_write_flags_property ", test_write_flags_property); - base = g_path_get_basename (argv[0]); - fprintf (stdout, "%s: SUCCESS\n", base); - g_free (base); - return 0; + return g_test_run (); } diff --git a/src/settings/plugins/keyfile/utils.c b/src/settings/plugins/keyfile/utils.c index e2bfc38c..3361d554 100644 --- a/src/settings/plugins/keyfile/utils.c +++ b/src/settings/plugins/keyfile/utils.c @@ -18,6 +18,8 @@ * (C) Copyright 2010 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -229,6 +231,7 @@ nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ DEFINE_KF_WRAPPER(string, gchar*, const gchar*); DEFINE_KF_WRAPPER(integer, gint, gint); +DEFINE_KF_WRAPPER(uint64, guint64, guint64); DEFINE_KF_WRAPPER(boolean, gboolean, gboolean); DEFINE_KF_WRAPPER(value, gchar*, const gchar*); diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h index 9a2e485b..1a7c2502 100644 --- a/src/settings/plugins/keyfile/utils.h +++ b/src/settings/plugins/keyfile/utils.h @@ -61,6 +61,7 @@ void nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ set_ctype value); DEFINE_KF_WRAPPER_PROTO(string, gchar*, const gchar*) DEFINE_KF_WRAPPER_PROTO(integer, gint, gint) +DEFINE_KF_WRAPPER_PROTO(uint64, guint64, guint64) DEFINE_KF_WRAPPER_PROTO(boolean, gboolean, gboolean) DEFINE_KF_WRAPPER_PROTO(value, gchar*, const gchar*) diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 5f3ebe25..d342e3f7 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -19,7 +19,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#include +#include "config.h" + #include #include #include @@ -40,7 +41,6 @@ #include #include #include -#include #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" @@ -98,75 +98,77 @@ write_array_of_uint (GKeyFile *file, } static void -ip4_dns_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) +dns_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) { - GArray *array; char **list; - int i, num = 0; - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY)); - - array = (GArray *) g_value_get_boxed (value); - if (!array || !array->len) - return; - - list = g_new0 (char *, array->len + 1); - - for (i = 0; i < array->len; i++) { - char *buf = g_new (char, INET_ADDRSTRLEN); - guint32 addr; - - addr = g_array_index (array, guint32, i); - nm_utils_inet4_ntop (addr, buf); - list[num++] = buf; + list = g_value_get_boxed (value); + if (list && list[0]) { + nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, + (const char **) list, g_strv_length (list)); } - - nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); - g_strfreev (list); } static void -write_ip4_values (GKeyFile *file, - const char *setting_name, - GPtrArray *array, - gboolean is_route) +write_ip_values (GKeyFile *file, + const char *setting_name, + GPtrArray *array, + const char *gateway, + gboolean is_route) { GString *output; - int i; - guint32 addr, gw, plen, metric; + int family, i; + const char *addr, *gw; + guint32 plen, metric; char key_name[30], *key_name_idx; if (!array->len) return; + family = !strcmp (setting_name, NM_SETTING_IP4_CONFIG_SETTING_NAME) ? AF_INET : AF_INET6; + strcpy (key_name, is_route ? "route" : "address"); key_name_idx = key_name + strlen (key_name); output = g_string_sized_new (2*INET_ADDRSTRLEN + 10); for (i = 0; i < array->len; i++) { - GArray *tuple = g_ptr_array_index (array, i); + if (is_route) { + NMIPRoute *route = array->pdata[i]; + + addr = nm_ip_route_get_dest (route); + plen = nm_ip_route_get_prefix (route); + gw = nm_ip_route_get_next_hop (route); + metric = MAX (0, nm_ip_route_get_metric (route)); + } else { + NMIPAddress *address = array->pdata[i]; - addr = g_array_index (tuple, guint32, 0); - plen = g_array_index (tuple, guint32, 1); - gw = g_array_index (tuple, guint32, 2); - metric = is_route ? g_array_index (tuple, guint32, 3) : 0; + addr = nm_ip_address_get_address (address); + plen = nm_ip_address_get_prefix (address); + gw = i == 0 ? gateway : NULL; + metric = 0; + } g_string_set_size (output, 0); - g_string_append_printf (output, "%s/%u", - nm_utils_inet4_ntop (addr, NULL), - (unsigned) plen); + g_string_append_printf (output, "%s/%u", addr, plen); if (metric || gw) { /* Older versions of the plugin do not support the form * "a.b.c.d/plen,,metric", so, we always have to write the - * gateway, even if it's 0.0.0.0. - * The current version support reading of the above form. */ - g_string_append_c (output, ','); - g_string_append (output, nm_utils_inet4_ntop (gw, NULL)); + * gateway, even if there isn't one. + * The current version supports reading of the above form. + */ + if (!gw) { + if (family == AF_INET) + gw = "0.0.0.0"; + else + gw = "::"; + } + + g_string_append_printf (output, ",%s", gw); if (metric) g_string_append_printf (output, ",%lu", (unsigned long) metric); } @@ -178,21 +180,20 @@ write_ip4_values (GKeyFile *file, } static void -ip4_addr_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) +addr_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) { GPtrArray *array; const char *setting_name = nm_setting_get_name (setting); - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); + const char *gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting)); array = (GPtrArray *) g_value_get_boxed (value); if (array && array->len) - write_ip4_values (file, setting_name, array, FALSE); + write_ip_values (file, setting_name, array, gateway, FALSE); } static void @@ -207,223 +208,30 @@ ip4_addr_label_writer (GKeyFile *file, } static void -ip4_route_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GPtrArray *array; - const char *setting_name = nm_setting_get_name (setting); - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); - - array = (GPtrArray *) g_value_get_boxed (value); - if (array && array->len) - write_ip4_values (file, setting_name, array, TRUE); -} - -static void -ip6_dns_writer (GKeyFile *file, +gateway_writer (GKeyFile *file, const char *keyfile_dir, const char *uuid, NMSetting *setting, const char *key, const GValue *value) { - GPtrArray *array; - GByteArray *byte_array; - char **list; - int i, num = 0; - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)); - - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) - return; - - list = g_new0 (char *, array->len + 1); - - for (i = 0; i < array->len; i++) { - char *buf = g_new (char, INET6_ADDRSTRLEN); - - byte_array = g_ptr_array_index (array, i); - nm_utils_inet6_ntop ((const struct in6_addr *) byte_array->data, buf); - list[num++] = buf; - } - - nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); - g_strfreev (list); -} - -static void -ip6_array_to_addr (GValueArray *values, - guint32 idx, - char *buf, - struct in6_addr *out_addr) -{ - GByteArray *byte_array; - GValue *addr_val; - const struct in6_addr *addr; - - addr_val = g_value_array_get_nth (values, idx); - byte_array = g_value_get_boxed (addr_val); - addr = (const struct in6_addr *) byte_array->data; - - nm_utils_inet6_ntop (addr, buf); - - if (out_addr) - *out_addr = *addr; -} - -static char * -ip6_array_to_addr_prefix (GValueArray *values, gboolean force_write_gateway) -{ - GValue *prefix_val; - char *ret = NULL; - GString *ip6_str; - char buf[INET6_ADDRSTRLEN]; - struct in6_addr addr; - - /* address */ - ip6_array_to_addr (values, 0, buf, NULL); - - /* Enough space for the address, '/', and the prefix */ - ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5); - - /* prefix */ - g_string_append (ip6_str, buf); - prefix_val = g_value_array_get_nth (values, 1); - g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val)); - - ip6_array_to_addr (values, 2, buf, &addr); - if (force_write_gateway || !IN6_IS_ADDR_UNSPECIFIED (&addr)) - g_string_append_printf (ip6_str, ",%s", buf); - - ret = ip6_str->str; - g_string_free (ip6_str, FALSE); - - return ret; -} - -static void -ip6_addr_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GPtrArray *array; - const char *setting_name = nm_setting_get_name (setting); - int i, j; - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); - - array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) - return; - - for (i = 0, j = 1; i < array->len; i++) { - GValueArray *values = g_ptr_array_index (array, i); - char *key_name, *ip6_addr; - - if (values->n_values != 3) { - nm_log_warn (LOGD_SETTINGS, "%s: error writing IP6 address %d (address array " - "length %d is not 3)", __func__, i, values->n_values); - continue; - } - - /* we allow omitting the gateway if it's :: */ - ip6_addr = ip6_array_to_addr_prefix (values, FALSE); - /* Write it out */ - key_name = g_strdup_printf ("address%d", j++); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, ip6_addr); - g_free (key_name); - g_free (ip6_addr); - } + /* skip */ } static void -ip6_route_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) +route_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) { GPtrArray *array; const char *setting_name = nm_setting_get_name (setting); - GString *output; - int i, j; - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE)); array = (GPtrArray *) g_value_get_boxed (value); - if (!array || !array->len) - return; - - for (i = 0, j = 1; i < array->len; i++) { - GValueArray *values = g_ptr_array_index (array, i); - char *key_name; - char *addr_str; - guint metric; - - output = g_string_new (""); - - /* Metric */ - value = g_value_array_get_nth (values, 3); - metric = g_value_get_uint (value); - - /* Address, prefix and next hop - * We allow omitting the gateway ::, if we also omit the metric - * and force writing of the gateway, if we add a non zero metric. - * The current version of the reader also supports the syntax - * "a:b:c::/plen,,metric" for a gateway ::. - * As older versions of the plugin, cannot read this form, - * we always write the gateway, whenever we also write the metric. - * But if possible, we omit them both (",::,0") or only the metric - * (",0"). - **/ - addr_str = ip6_array_to_addr_prefix (values, metric != 0); - g_string_append (output, addr_str); - g_free (addr_str); - - if (metric != 0) - g_string_append_printf (output, ",%u", metric); - - /* Write it out */ - key_name = g_strdup_printf ("route%d", j++); - nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); - g_free (key_name); - - g_string_free (output, TRUE); - } -} - - -static void -mac_address_writer (GKeyFile *file, - const char *keyfile_dir, - const char *uuid, - NMSetting *setting, - const char *key, - const GValue *value) -{ - GByteArray *array; - const char *setting_name = nm_setting_get_name (setting); - char *mac; - - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); - - array = (GByteArray *) g_value_get_boxed (value); - if (!array || !array->len) - return; - - mac = nm_utils_hwaddr_ntoa_len (array->data, array->len); - nm_keyfile_plugin_kf_set_string (file, setting_name, key, mac); - g_free (mac); + if (array && array->len) + write_ip_values (file, setting_name, array, NULL, TRUE); } static void @@ -472,24 +280,29 @@ ssid_writer (GKeyFile *file, const char *key, const GValue *value) { - GByteArray *array; + GBytes *bytes; + const guint8 *ssid_data; + gsize ssid_len; const char *setting_name = nm_setting_get_name (setting); gboolean new_format = TRUE; unsigned int semicolons = 0; int i, *tmp_array; char *ssid; - g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); + g_return_if_fail (G_VALUE_HOLDS (value, G_TYPE_BYTES)); - array = (GByteArray *) g_value_get_boxed (value); - if (!array || !array->len) + bytes = g_value_get_boxed (value); + if (!bytes) + return; + ssid_data = g_bytes_get_data (bytes, &ssid_len); + if (ssid_len == 0) return; /* Check whether each byte is printable. If not, we have to use an * integer list, otherwise we can just use a string. */ - for (i = 0; i < array->len; i++) { - char c = array->data[i] & 0xFF; + for (i = 0; i < ssid_len; i++) { + char c = ssid_data[i] & 0xFF; if (!g_ascii_isprint (c)) { new_format = FALSE; break; @@ -499,26 +312,26 @@ ssid_writer (GKeyFile *file, } if (new_format) { - ssid = g_malloc0 (array->len + semicolons + 1); + ssid = g_malloc0 (ssid_len + semicolons + 1); if (semicolons == 0) - memcpy (ssid, array->data, array->len); + memcpy (ssid, ssid_data, ssid_len); else { /* Escape semicolons with backslashes to make strings * containing ';', such as '16;17;' unambiguous */ int j = 0; - for (i = 0; i < array->len; i++) { - if (array->data[i] == ';') + for (i = 0; i < ssid_len; i++) { + if (ssid_data[i] == ';') ssid[j++] = '\\'; - ssid[j++] = array->data[i]; + ssid[j++] = ssid_data[i]; } } nm_keyfile_plugin_kf_set_string (file, setting_name, key, ssid); g_free (ssid); } else { - tmp_array = g_new (gint, array->len); - for (i = 0; i < array->len; i++) - tmp_array[i] = (int) array->data[i]; - nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, array->len); + tmp_array = g_new (gint, ssid_len); + for (i = 0; i < ssid_len; i++) + tmp_array[i] = (int) ssid_data[i]; + nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, ssid_len); g_free (tmp_array); } } @@ -555,7 +368,7 @@ typedef struct ObjectType { NMSetting8021xCKScheme (*scheme_func) (NMSetting8021x *setting); NMSetting8021xCKFormat (*format_func) (NMSetting8021x *setting); const char * (*path_func) (NMSetting8021x *setting); - const GByteArray * (*blob_func) (NMSetting8021x *setting); + GBytes * (*blob_func) (NMSetting8021x *setting); } ObjectType; static const ObjectType objtypes[10] = { @@ -612,7 +425,8 @@ static const ObjectType objtypes[10] = { static gboolean write_cert_key_file (const char *path, - const GByteArray *data, + const guint8 *data, + gsize data_len, GError **error) { char *tmppath; @@ -627,7 +441,7 @@ write_cert_key_file (const char *path, errno = 0; fd = mkstemp (tmppath); if (fd < 0) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not create temporary file for '%s': %d", path, errno); goto out; @@ -638,18 +452,18 @@ write_cert_key_file (const char *path, if (fchmod (fd, S_IRUSR | S_IWUSR) != 0) { close (fd); unlink (tmppath); - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not set permissions for temporary file '%s': %d", path, errno); goto out; } errno = 0; - written = write (fd, data->data, data->len); - if (written != data->len) { + written = write (fd, data, data_len); + if (written != data_len) { close (fd); unlink (tmppath); - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not write temporary file for '%s': %d", path, errno); goto out; @@ -662,7 +476,7 @@ write_cert_key_file (const char *path, success = TRUE; else { unlink (tmppath); - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not rename temporary file to '%s': %d", path, errno); } @@ -714,13 +528,16 @@ cert_writer (GKeyFile *file, nm_keyfile_plugin_kf_set_string (file, setting_name, key, path); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { - const GByteArray *blob; + GBytes *blob; + const guint8 *blob_data; + gsize blob_len; gboolean success; GError *error = NULL; char *new_path; blob = objtype->blob_func (NM_SETTING_802_1X (setting)); g_assert (blob); + blob_data = g_bytes_get_data (blob, &blob_len); if (objtype->format_func) { /* Get the extension for a private key */ @@ -729,7 +546,7 @@ cert_writer (GKeyFile *file, ext = "p12"; } else { /* DER or PEM format certificate? */ - if (blob->len > 2 && blob->data[0] == 0x30 && blob->data[1] == 0x82) + if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82) ext = "der"; } @@ -739,7 +556,7 @@ cert_writer (GKeyFile *file, new_path = g_strdup_printf ("%s/%s-%s.%s", keyfile_dir, uuid, objtype->suffix, ext); g_assert (new_path); - success = write_cert_key_file (new_path, blob, &error); + success = write_cert_key_file (new_path, blob_data, blob_len, &error); if (success) { /* Write the path value to the keyfile */ nm_keyfile_plugin_kf_set_string (file, setting_name, key, new_path); @@ -774,54 +591,33 @@ static KeyWriter key_writers[] = { { NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, setting_alias_writer }, - { NM_SETTING_BRIDGE_SETTING_NAME, - NM_SETTING_BRIDGE_MAC_ADDRESS, - mac_address_writer }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ADDRESSES, - ip4_addr_writer }, + NM_SETTING_IP_CONFIG_ADDRESSES, + addr_writer }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, "address-labels", ip4_addr_label_writer }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ADDRESSES, - ip6_addr_writer }, + NM_SETTING_IP_CONFIG_ADDRESSES, + addr_writer }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_ROUTES, - ip4_route_writer }, + NM_SETTING_IP_CONFIG_GATEWAY, + gateway_writer }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_ROUTES, - ip6_route_writer }, + NM_SETTING_IP_CONFIG_GATEWAY, + gateway_writer }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_SETTING_IP4_CONFIG_DNS, - ip4_dns_writer }, + NM_SETTING_IP_CONFIG_ROUTES, + route_writer }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_SETTING_IP6_CONFIG_DNS, - ip6_dns_writer }, - { NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_MAC_ADDRESS, - mac_address_writer }, - { NM_SETTING_WIRED_SETTING_NAME, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - mac_address_writer }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_MAC_ADDRESS, - mac_address_writer }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, - mac_address_writer }, - { NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_WIRELESS_BSSID, - mac_address_writer }, - { NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_SETTING_BLUETOOTH_BDADDR, - mac_address_writer }, - { NM_SETTING_INFINIBAND_SETTING_NAME, - NM_SETTING_INFINIBAND_MAC_ADDRESS, - mac_address_writer }, - { NM_SETTING_WIMAX_SETTING_NAME, - NM_SETTING_WIMAX_MAC_ADDRESS, - mac_address_writer }, + NM_SETTING_IP_CONFIG_ROUTES, + route_writer }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS, + dns_writer }, + { NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_DNS, + dns_writer }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, ssid_writer }, @@ -896,7 +692,8 @@ write_setting_value (NMSetting *setting, if (pspec && (pspec->flags & NM_SETTING_PARAM_SECRET) && !NM_IS_SETTING_VPN (setting)) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) + g_assert_not_reached (); if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) return; } @@ -926,49 +723,53 @@ write_setting_value (NMSetting *setting, numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value)); nm_keyfile_plugin_kf_set_value (info->keyfile, setting_name, key, numstr); g_free (numstr); + } else if (type == G_TYPE_INT64) { + char *numstr; + + numstr = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (value)); + nm_keyfile_plugin_kf_set_value (info->keyfile, setting_name, key, numstr); + g_free (numstr); } else if (type == G_TYPE_BOOLEAN) { nm_keyfile_plugin_kf_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); } else if (type == G_TYPE_CHAR) { nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value)); - } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { - GByteArray *array; + } else if (type == G_TYPE_BYTES) { + GBytes *bytes; + const guint8 *data; + gsize len = 0; - array = (GByteArray *) g_value_get_boxed (value); - if (array && array->len > 0) { + bytes = g_value_get_boxed (value); + data = bytes ? g_bytes_get_data (bytes, &len) : NULL; + + if (data != NULL && len > 0) { int *tmp_array; int i; - tmp_array = g_new (gint, array->len); - for (i = 0; i < array->len; i++) - tmp_array[i] = (int) array->data[i]; + tmp_array = g_new (gint, len); + for (i = 0; i < len; i++) + tmp_array[i] = (int) data[i]; - nm_keyfile_plugin_kf_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list (info->keyfile, setting_name, key, tmp_array, len); g_free (tmp_array); } - } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { - GSList *list; - GSList *iter; - - list = (GSList *) g_value_get_boxed (value); - if (list) { - char **array; - int i = 0; + } else if (type == G_TYPE_STRV) { + char **array; - array = g_new (char *, g_slist_length (list)); - for (iter = list; iter; iter = iter->next) - array[i++] = iter->data; - - nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i); - g_free (array); - } - } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { + array = (char **) g_value_get_boxed (value); + nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, g_strv_length (array)); + } else if (type == G_TYPE_HASH_TABLE) { write_hash_of_string (info->keyfile, setting, key, value); - } else if (type == DBUS_TYPE_G_UINT_ARRAY) { + } else if (type == G_TYPE_ARRAY) { if (!write_array_of_uint (info->keyfile, setting, key, value)) { nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", setting_name, key, g_type_name (type)); } - } else { + } else if (G_VALUE_HOLDS_FLAGS (value)) { + /* Flags are guint but GKeyFile has no uint reader, just uint64 */ + nm_keyfile_plugin_kf_set_uint64 (info->keyfile, setting_name, key, (guint64) g_value_get_flags (value)); + } else if (G_VALUE_HOLDS_ENUM (value)) + nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (gint) g_value_get_enum (value)); + else { nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", setting_name, key, g_type_name (type)); } @@ -1021,11 +822,7 @@ _internal_write_connection (NMConnection *connection, } id = nm_connection_get_id (connection); - if (!id) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, - "%s.%d: connection had no ID", __FILE__, __LINE__); - return FALSE; - } + g_assert (id && *id); info.keyfile = key_file = g_key_file_new (); info.keyfile_dir = keyfile_dir; @@ -1065,7 +862,7 @@ _internal_write_connection (NMConnection *connection, * is edited to contain the same ID as the other one. * Give up. */ - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "%s.%d: could not find suitable keyfile file name (%s already used)", __FILE__, __LINE__, path); g_free (path); @@ -1082,7 +879,7 @@ _internal_write_connection (NMConnection *connection, g_file_set_contents (path, data, len, &local_err); if (local_err) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "%s.%d: error writing to file '%s': %s", __FILE__, __LINE__, path, local_err->message); g_error_free (local_err); @@ -1091,13 +888,13 @@ _internal_write_connection (NMConnection *connection, } if (chown (path, owner_uid, owner_grp) < 0) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "%s.%d: error chowning '%s': %d", __FILE__, __LINE__, path, errno); unlink (path); } else { if (chmod (path, S_IRUSR | S_IWUSR) < 0) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "%s.%d: error setting permissions on '%s': %d", __FILE__, __LINE__, path, errno); unlink (path); diff --git a/src/settings/tests/Makefile.am b/src/settings/tests/Makefile.am deleted file mode 100644 index 4115d4ba..00000000 --- a/src/settings/tests/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_srcdir)/src/settings \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) - -noinst_PROGRAMS = \ - test-wired-defname - -####### wired defname test ####### - -test_wired_defname_SOURCES = \ - test-wired-defname.c - -test_wired_defname_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - -########################################### - -TESTS = test-wired-defname diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in deleted file mode 100644 index 7016c27f..00000000 --- a/src/settings/tests/Makefile.in +++ /dev/null @@ -1,854 +0,0 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -noinst_PROGRAMS = test-wired-defname$(EXEEXT) -TESTS = test-wired-defname$(EXEEXT) -subdir = src/settings/tests -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/build-aux/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/gnome-code-coverage.m4 \ - $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ - $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ - $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -PROGRAMS = $(noinst_PROGRAMS) -am_test_wired_defname_OBJECTS = test-wired-defname.$(OBJEXT) -test_wired_defname_OBJECTS = $(am_test_wired_defname_OBJECTS) -test_wired_defname_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(test_wired_defname_SOURCES) -DIST_SOURCES = $(test_wired_defname_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - mgn=''; \ - brg=''; \ - std=''; \ - fi; \ -} -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALL_LINGUAS = @ALL_LINGUAS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CKDB_PATH = @CKDB_PATH@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DBUS_CFLAGS = @DBUS_CFLAGS@ -DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ -DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ -DBUS_LIBS = @DBUS_LIBS@ -DBUS_SYS_DIR = @DBUS_SYS_DIR@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DHCLIENT_PATH = @DHCLIENT_PATH@ -DHCPCD_PATH = @DHCPCD_PATH@ -DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ -DLLTOOL = @DLLTOOL@ -DNSMASQ_PATH = @DNSMASQ_PATH@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GENHTML = @GENHTML@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ -GLIB_LIBS = @GLIB_LIBS@ -GLIB_MAKEFILE = @GLIB_MAKEFILE@ -GLIB_MKENUMS = @GLIB_MKENUMS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ -GNUTLS_LIBS = @GNUTLS_LIBS@ -GREP = @GREP@ -GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ -GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ -GTKDOC_MKPDF = @GTKDOC_MKPDF@ -GTKDOC_REBASE = @GTKDOC_REBASE@ -GUDEV_CFLAGS = @GUDEV_CFLAGS@ -GUDEV_LIBS = @GUDEV_LIBS@ -HTML_DIR = @HTML_DIR@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ -INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ -INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ -INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ -INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ -INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ -INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ -IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ -KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ -LCOV = @LCOV@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBDL = @LIBDL@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBM = @LIBM@ -LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ -LIBNDP_LIBS = @LIBNDP_LIBS@ -LIBNL_CFLAGS = @LIBNL_CFLAGS@ -LIBNL_LIBS = @LIBNL_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ -LIBSOUP_LIBS = @LIBSOUP_LIBS@ -LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ -LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ -MM_GLIB_LIBS = @MM_GLIB_LIBS@ -MOC = @MOC@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NEWT_CFLAGS = @NEWT_CFLAGS@ -NEWT_LIBS = @NEWT_LIBS@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ -NM_MICRO_VERSION = @NM_MICRO_VERSION@ -NM_MINOR_VERSION = @NM_MINOR_VERSION@ -NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ -NM_VERSION = @NM_VERSION@ -NSS_CFLAGS = @NSS_CFLAGS@ -NSS_LIBS = @NSS_LIBS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POLKIT_CFLAGS = @POLKIT_CFLAGS@ -POLKIT_LIBS = @POLKIT_LIBS@ -POSUB = @POSUB@ -PPPD_PATH = @PPPD_PATH@ -PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ -PPPOE_PATH = @PPPOE_PATH@ -QT_CFLAGS = @QT_CFLAGS@ -QT_LIBS = @QT_LIBS@ -RANLIB = @RANLIB@ -READLINE_LIBS = @READLINE_LIBS@ -SED = @SED@ -SELINUX_CFLAGS = @SELINUX_CFLAGS@ -SELINUX_LIBS = @SELINUX_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ -SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ -SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ -SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ -SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ -SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ -SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ -USE_NLS = @USE_NLS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VALGRIND_RULES = @VALGRIND_RULES@ -VAPIGEN = @VAPIGEN@ -VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ -VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -intltool__v_merge_options_ = @intltool__v_merge_options_@ -intltool__v_merge_options_0 = @intltool__v_merge_options_0@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nmbinary = @nmbinary@ -nmconfdir = @nmconfdir@ -nmdatadir = @nmdatadir@ -nmrundir = @nmrundir@ -nmstatedir = @nmstatedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -systemdsystemunitdir = @systemdsystemunitdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_dhclient = @with_dhclient@ -with_dhcpcd = @with_dhcpcd@ -with_netconfig = @with_netconfig@ -with_resolvconf = @with_resolvconf@ -with_valgrind = @with_valgrind@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_srcdir)/src/settings \ - -DG_LOG_DOMAIN=\""NetworkManager"\" \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) - - -####### wired defname test ####### -test_wired_defname_SOURCES = \ - test-wired-defname.c - -test_wired_defname_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/tests/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/settings/tests/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -test-wired-defname$(EXEEXT): $(test_wired_defname_OBJECTS) $(test_wired_defname_DEPENDENCIES) $(EXTRA_test_wired_defname_DEPENDENCIES) - @rm -f test-wired-defname$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_wired_defname_OBJECTS) $(test_wired_defname_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wired-defname.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - $(am__tty_colors); \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - col=$$red; res=XPASS; \ - ;; \ - *) \ - col=$$grn; res=PASS; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$tst[\ \ ]*) \ - xfail=`expr $$xfail + 1`; \ - col=$$lgn; res=XFAIL; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - col=$$red; res=FAIL; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - col=$$blu; res=SKIP; \ - fi; \ - echo "$${col}$$res$${std}: $$tst"; \ - done; \ - if test "$$all" -eq 1; then \ - tests="test"; \ - All=""; \ - else \ - tests="tests"; \ - All="All "; \ - fi; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="$$All$$all $$tests passed"; \ - else \ - if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ - banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all $$tests failed"; \ - else \ - if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ - banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - skipped="($$skip test was not run)"; \ - else \ - skipped="($$skip tests were not run)"; \ - fi; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - if test "$$failed" -eq 0; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$${col}$$dashes$${std}"; \ - echo "$${col}$$banner$${std}"; \ - test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ - test -z "$$report" || echo "$${col}$$report$${std}"; \ - echo "$${col}$$dashes$${std}"; \ - test "$$failed" -eq 0; \ - else :; fi - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/settings/tests/test-wired-defname.c b/src/settings/tests/test-wired-defname.c deleted file mode 100644 index 2d88dd77..00000000 --- a/src/settings/tests/test-wired-defname.c +++ /dev/null @@ -1,139 +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, 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2010 Red Hat, Inc. - * - */ - -#include -#include - -#include -#include -#include "nm-settings-utils.h" - -static NMConnection * -_new_connection (const char *id) -{ - NMConnection *a; - NMSetting *setting; - - a = nm_connection_new (); - setting = nm_setting_connection_new (); - g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NULL); - nm_connection_add_setting (a, setting); - return a; -} - -/*******************************************/ - -static void -test_defname_no_connections (void) -{ - GHashTable *hash; - char *name; - - hash = g_hash_table_new (g_direct_hash, g_direct_equal); - - name = nm_settings_utils_get_default_wired_name (hash); - g_assert_cmpstr (name, ==, "Wired connection 1"); - - g_hash_table_destroy (hash); -} - -/*******************************************/ - -static void -test_defname_no_conflict (void) -{ - GHashTable *hash; - char *name; - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); - - g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf")); - g_hash_table_insert (hash, "b", _new_connection ("work wifi")); - g_hash_table_insert (hash, "c", _new_connection ("random gsm connection")); - - name = nm_settings_utils_get_default_wired_name (hash); - g_assert_cmpstr (name, ==, "Wired connection 1"); - - g_hash_table_destroy (hash); -} - -/*******************************************/ - -static void -test_defname_conflict (void) -{ - GHashTable *hash; - char *name; - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); - - g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf")); - g_hash_table_insert (hash, "b", _new_connection ("Wired connection 1")); - g_hash_table_insert (hash, "c", _new_connection ("random gsm connection")); - - name = nm_settings_utils_get_default_wired_name (hash); - g_assert_cmpstr (name, ==, "Wired connection 2"); - - g_hash_table_destroy (hash); -} - -/*******************************************/ - -static void -test_defname_multiple_conflicts (void) -{ - GHashTable *hash; - char *name; - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref); - - g_hash_table_insert (hash, "a", _new_connection ("random gsm connection")); - g_hash_table_insert (hash, "b", _new_connection ("home wifi")); - g_hash_table_insert (hash, "c", _new_connection ("Wired connection 1")); - g_hash_table_insert (hash, "d", _new_connection ("Wired connection 2")); - g_hash_table_insert (hash, "e", _new_connection ("Wired connection 3")); - g_hash_table_insert (hash, "f", _new_connection ("work wifi")); - g_hash_table_insert (hash, "g", _new_connection ("a vpn")); - - name = nm_settings_utils_get_default_wired_name (hash); - g_assert_cmpstr (name, ==, "Wired connection 4"); - - g_hash_table_destroy (hash); -} - -/*******************************************/ - -int -main (int argc, char **argv) -{ -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif - - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/defname/no_connections", test_defname_no_connections); - g_test_add_func ("/defname/no_conflict", test_defname_no_conflict); - g_test_add_func ("/defname/conflict", test_defname_conflict); - g_test_add_func ("/defname/multiple_conflicts", test_defname_multiple_conflicts); - - return g_test_run (); -} - diff --git a/src/supplicant-manager/nm-call-store.c b/src/supplicant-manager/nm-call-store.c index 4b427549..6e910a96 100644 --- a/src/supplicant-manager/nm-call-store.c +++ b/src/supplicant-manager/nm-call-store.c @@ -19,6 +19,8 @@ * Copyright (C) 2010 Red Hat, Inc. */ +#include "config.h" + #include "nm-call-store.h" #include "nm-logging.h" @@ -44,7 +46,13 @@ nm_call_store_add (NMCallStore *store, g_return_if_fail (store != NULL); g_return_if_fail (proxy != NULL); - g_return_if_fail (call != NULL); + + if (!call) { + /* Allow calling nm_call_store_add() with NULL @call for convenience. + * This way you can pass the result of dbus_g_proxy_begin_call() directly + * to nm_call_store_add() without checking for NULL. */ + return; + } calls = g_hash_table_lookup (store, proxy); if (!calls) { diff --git a/src/supplicant-manager/nm-call-store.h b/src/supplicant-manager/nm-call-store.h index b24c97a4..bcee54cf 100644 --- a/src/supplicant-manager/nm-call-store.h +++ b/src/supplicant-manager/nm-call-store.h @@ -18,8 +18,8 @@ * (C) Copyright 2007 Novell, Inc. */ -#ifndef NM_CALLBACK_STORE_H -#define NM_CALLBACK_STORE_H +#ifndef __NETWORKMANAGER_CALLBACK_STORE_H__ +#define __NETWORKMANAGER_CALLBACK_STORE_H__ #include #include @@ -38,4 +38,4 @@ void nm_call_store_remove (NMCallStore *store, void nm_call_store_clear (NMCallStore *store); void nm_call_store_destroy (NMCallStore *store); -#endif /* NM_CALLBACK_STORE_H */ +#endif /* __NETWORKMANAGER_CALLBACK_STORE_H__ */ diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c index 438b436e..9ae87095 100644 --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -19,14 +19,11 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifdef HAVE_CONFIG_H -#include -#endif +#include "config.h" #include #include #include -#include #include #include "nm-supplicant-config.h" @@ -166,7 +163,7 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self, static gboolean nm_supplicant_config_add_blob (NMSupplicantConfig *self, const char *key, - const GByteArray *value, + GBytes *value, const char *blobid) { NMSupplicantConfigPrivate *priv; @@ -174,16 +171,20 @@ nm_supplicant_config_add_blob (NMSupplicantConfig *self, ConfigOption *opt; OptType type; GByteArray *blob; + const guint8 *data; + gsize data_len; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (value->len > 0, FALSE); g_return_val_if_fail (blobid != NULL, FALSE); + data = g_bytes_get_data (value, &data_len); + g_return_val_if_fail (data_len > 0, FALSE); + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); - type = nm_supplicant_settings_verify_setting (key, (const char *) value->data, value->len); + type = nm_supplicant_settings_verify_setting (key, (const char *) data, data_len); if (type == TYPE_INVALID) { nm_log_warn (LOGD_SUPPLICANT, "Key '%s' and/or it's contained value is invalid.", key); return FALSE; @@ -195,8 +196,8 @@ nm_supplicant_config_add_blob (NMSupplicantConfig *self, return FALSE; } - blob = g_byte_array_sized_new (value->len); - g_byte_array_append (blob, value->data, value->len); + blob = g_byte_array_sized_new (data_len); + g_byte_array_append (blob, data, data_len); opt = g_slice_new0 (ConfigOption); opt->value = g_strdup_printf ("blob://%s", blobid); @@ -328,9 +329,6 @@ nm_supplicant_config_get_blobs (NMSupplicantConfig * self) return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->blobs; } -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] - #define TWO_GHZ_FREQS "2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,2484" #define FIVE_GHZ_FREQS "4915,4920,4925,4935,4940,4945,4960,4980,5035,5040,5045,5055,5060,5080," \ "5170,5180,5190,5200,5210,5220,5230,5240,5260,5280,5300,5320,5500," \ @@ -346,7 +344,8 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, NMSupplicantConfigPrivate *priv; gboolean is_adhoc, is_ap; const char *mode, *band; - const GByteArray *id; + GBytes *ssid; + const char *bssid; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); @@ -361,8 +360,11 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, else priv->ap_scan = 1; - id = nm_setting_wireless_get_ssid (setting); - if (!nm_supplicant_config_add_option (self, "ssid", (char *) id->data, id->len, FALSE)) { + ssid = nm_setting_wireless_get_ssid (setting); + if (!nm_supplicant_config_add_option (self, "ssid", + (char *) g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid), + FALSE)) { nm_log_warn (LOGD_SUPPLICANT, "Error adding SSID to supplicant config."); return FALSE; } @@ -401,19 +403,14 @@ nm_supplicant_config_add_setting_wireless (NMSupplicantConfig * self, return FALSE; } - id = nm_setting_wireless_get_bssid (setting); - if (id && id->len) { - char *str_bssid; - - str_bssid = g_strdup_printf (MAC_FMT, MAC_ARG (id->data)); + bssid = nm_setting_wireless_get_bssid (setting); + if (bssid) { if (!nm_supplicant_config_add_option (self, "bssid", - str_bssid, strlen (str_bssid), + bssid, strlen (bssid), FALSE)) { - g_free (str_bssid); nm_log_warn (LOGD_SUPPLICANT, "Error adding BSSID to supplicant config."); return FALSE; } - g_free (str_bssid); } band = nm_setting_wireless_get_band (setting); @@ -496,7 +493,7 @@ get_blob_id (const char *name, const char *seed_uid) } #define ADD_BLOB_VAL(field, name, con_uid) \ - if (field && field->len) { \ + if (field && g_bytes_get_size (field)) { \ char *uid = get_blob_id (name, con_uid); \ success = nm_supplicant_config_add_blob (self, name, field, uid); \ g_free (uid); \ @@ -543,8 +540,8 @@ add_wep_key (NMSupplicantConfig *self, const char *name, NMWepKeyType wep_type) { - char *value; - gboolean success; + GBytes *bytes; + gboolean success = FALSE; size_t key_len = key ? strlen (key) : 0; if (!key || !key_len) @@ -553,9 +550,15 @@ add_wep_key (NMSupplicantConfig *self, if ( (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) || (wep_type == NM_WEP_KEY_TYPE_KEY)) { if ((key_len == 10) || (key_len == 26)) { - value = nm_utils_hexstr2bin (key, strlen (key)); - success = nm_supplicant_config_add_option (self, name, value, key_len / 2, TRUE); - g_free (value); + bytes = nm_utils_hexstr2bin (key); + if (bytes) { + success = nm_supplicant_config_add_option (self, + name, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + TRUE); + g_bytes_unref (bytes); + } if (!success) { nm_log_warn (LOGD_SUPPLICANT, "Error adding %s to supplicant config.", name); return FALSE; @@ -591,8 +594,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, NMSetting8021x *setting_8021x, const char *con_uuid) { - char *value; - gboolean success; + gboolean success = FALSE; const char *key_mgmt, *auth_alg; const char *psk; @@ -613,10 +615,18 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, size_t psk_len = strlen (psk); if (psk_len == 64) { + GBytes *bytes; + /* Hex PSK */ - value = nm_utils_hexstr2bin (psk, psk_len); - success = nm_supplicant_config_add_option (self, "psk", value, psk_len / 2, TRUE); - g_free (value); + bytes = nm_utils_hexstr2bin (psk); + if (bytes) { + success = nm_supplicant_config_add_option (self, + "psk", + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + TRUE); + g_bytes_unref (bytes); + } if (!success) { nm_log_warn (LOGD_SUPPLICANT, "Error adding 'psk' to supplicant config."); return FALSE; @@ -654,6 +664,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self, const char *wep1 = nm_setting_wireless_security_get_wep_key (setting, 1); const char *wep2 = nm_setting_wireless_security_get_wep_key (setting, 2); const char *wep3 = nm_setting_wireless_security_get_wep_key (setting, 3); + char *value; if (!add_wep_key (self, wep0, "wep_key0", wep_type)) return FALSE; @@ -732,7 +743,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, const char *peapver, *value, *path; gboolean success, added; GString *phase1, *phase2; - const GByteArray *array; + GBytes *bytes; gboolean fast = FALSE; guint32 i, num_eap; gboolean fast_provisoning_allowed = FALSE; @@ -748,12 +759,12 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, if (!add_string_val (self, value, "password", FALSE, TRUE)) return FALSE; } else { - array = nm_setting_802_1x_get_password_raw (setting); - if (array) { + bytes = nm_setting_802_1x_get_password_raw (setting); + if (bytes) { success = nm_supplicant_config_add_option (self, "password", - (const char *)array->data, - array->len, + (const char *) g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), TRUE); if (!success) { nm_log_warn (LOGD_SUPPLICANT, "Error adding password-raw to supplicant config."); @@ -894,8 +905,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, /* CA certificate */ switch (nm_setting_802_1x_get_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_ca_cert_blob (setting); - ADD_BLOB_VAL (array, "ca_cert", con_uuid); + bytes = nm_setting_802_1x_get_ca_cert_blob (setting); + ADD_BLOB_VAL (bytes, "ca_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_ca_cert_path (setting); @@ -909,8 +920,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, /* Phase 2 CA certificate */ switch (nm_setting_802_1x_get_phase2_ca_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); - ADD_BLOB_VAL (array, "ca_cert2", con_uuid); + bytes = nm_setting_802_1x_get_phase2_ca_cert_blob (setting); + ADD_BLOB_VAL (bytes, "ca_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_ca_cert_path (setting); @@ -937,8 +948,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, added = FALSE; switch (nm_setting_802_1x_get_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_private_key_blob (setting); - ADD_BLOB_VAL (array, "private_key", con_uuid); + bytes = nm_setting_802_1x_get_private_key_blob (setting); + ADD_BLOB_VAL (bytes, "private_key", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: @@ -975,8 +986,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, */ switch (nm_setting_802_1x_get_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_client_cert_blob (setting); - ADD_BLOB_VAL (array, "client_cert", con_uuid); + bytes = nm_setting_802_1x_get_client_cert_blob (setting); + ADD_BLOB_VAL (bytes, "client_cert", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_client_cert_path (setting); @@ -993,8 +1004,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, added = FALSE; switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_phase2_private_key_blob (setting); - ADD_BLOB_VAL (array, "private_key2", con_uuid); + bytes = nm_setting_802_1x_get_phase2_private_key_blob (setting); + ADD_BLOB_VAL (bytes, "private_key2", con_uuid); added = TRUE; break; case NM_SETTING_802_1X_CK_SCHEME_PATH: @@ -1021,7 +1032,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, * isn't decrypted at all. */ value = nm_setting_802_1x_get_phase2_private_key_password (setting); - if (!add_string_val (self, value, "private_key_passwd2", FALSE, TRUE)) + if (!add_string_val (self, value, "private_key2_passwd", FALSE, TRUE)) return FALSE; } @@ -1031,8 +1042,8 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, */ switch (nm_setting_802_1x_get_phase2_client_cert_scheme (setting)) { case NM_SETTING_802_1X_CK_SCHEME_BLOB: - array = nm_setting_802_1x_get_phase2_client_cert_blob (setting); - ADD_BLOB_VAL (array, "client_cert2", con_uuid); + bytes = nm_setting_802_1x_get_phase2_client_cert_blob (setting); + ADD_BLOB_VAL (bytes, "client_cert2", con_uuid); break; case NM_SETTING_802_1X_CK_SCHEME_PATH: path = nm_setting_802_1x_get_phase2_client_cert_path (setting); diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h index 75d6b779..482e3545 100644 --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifndef NM_SUPPLICANT_CONFIG_H -#define NM_SUPPLICANT_CONFIG_H +#ifndef __NETWORKMANAGER_SUPPLICANT_CONFIG_H__ +#define __NETWORKMANAGER_SUPPLICANT_CONFIG_H__ #include #include diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 15138dc8..02b82b7e 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -19,7 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include #include @@ -1033,12 +1034,11 @@ add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); GError *err = NULL; - guint tmp; priv->blobs_left--; nm_call_store_remove (priv->assoc_pcalls, proxy, call_id); - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message); emit_error_helper (self, err); g_error_free (err); @@ -1080,7 +1080,7 @@ add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) add_blob_cb, self, NULL, - DBUS_TYPE_STRING, name, + G_TYPE_STRING, name, DBUS_TYPE_G_UCHAR_ARRAY, data, G_TYPE_INVALID); nm_call_store_add (priv->assoc_pcalls, priv->iface_proxy, call); @@ -1472,12 +1472,12 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) object_class->get_property = get_property; /* Properties */ - g_object_class_install_property (object_class, PROP_SCANNING, - g_param_spec_boolean ("scanning", - "Scanning", - "Scanning", - FALSE, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_SCANNING, + g_param_spec_boolean ("scanning", "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); /* Signals */ signals[STATE] = diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index 633c16cc..0112e40e 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -19,11 +19,10 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifndef NM_SUPPLICANT_INTERFACE_H -#define NM_SUPPLICANT_INTERFACE_H +#ifndef __NETWORKMANAGER_SUPPLICANT_INTERFACE_H__ +#define __NETWORKMANAGER_SUPPLICANT_INTERFACE_H__ #include -#include #include "nm-supplicant-types.h" /* diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index f146b239..01e35929 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -19,6 +19,8 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include @@ -405,11 +407,11 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) object_class->set_property = set_property; object_class->dispose = dispose; - g_object_class_install_property (object_class, PROP_AVAILABLE, - g_param_spec_boolean (NM_SUPPLICANT_MANAGER_AVAILABLE, - "Available", - "Available", - FALSE, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_AVAILABLE, + g_param_spec_boolean (NM_SUPPLICANT_MANAGER_AVAILABLE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); } diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h index 9e2f3b21..5e7f1eb5 100644 --- a/src/supplicant-manager/nm-supplicant-manager.h +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifndef NM_SUPPLICANT_MANAGER_H -#define NM_SUPPLICANT_MANAGER_H +#ifndef __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ +#define __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ #include #include "nm-supplicant-types.h" @@ -65,4 +65,4 @@ void nm_supplicant_manager_iface_release (NMSupplicantManager *mgr, gboolean nm_supplicant_manager_available (NMSupplicantManager *mgr); -#endif /* NM_SUPPLICANT_MANAGER_H */ +#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */ diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.c b/src/supplicant-manager/nm-supplicant-settings-verify.c index f7d4ca58..1328fd51 100644 --- a/src/supplicant-manager/nm-supplicant-settings-verify.c +++ b/src/supplicant-manager/nm-supplicant-settings-verify.c @@ -18,6 +18,8 @@ * Copyright (C) 2006 - 2012 Red Hat, Inc. */ +#include "config.h" + #include #include #include @@ -137,7 +139,7 @@ static const struct Opt opt_table[] = { { "proactive_key_caching", TYPE_INT, 0, 1, FALSE, NULL }, { "bgscan", TYPE_BYTES, 0, 0, FALSE, NULL }, { "pac_file", TYPE_BYTES, 0, 1024, FALSE, NULL }, - { "freq_list", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "freq_list", TYPE_KEYWORD, 0, 0, FALSE, NULL }, }; diff --git a/src/supplicant-manager/nm-supplicant-settings-verify.h b/src/supplicant-manager/nm-supplicant-settings-verify.h index eb213e0e..920343ba 100644 --- a/src/supplicant-manager/nm-supplicant-settings-verify.h +++ b/src/supplicant-manager/nm-supplicant-settings-verify.h @@ -18,8 +18,8 @@ * Copyright (C) 2006 - 2008 Red Hat, Inc. */ -#ifndef NM_SUPPLICANT_SETTINGS_VERIFY_H -#define NM_SUPPLICANT_SETTINGS_VERIFY_H +#ifndef __NETWORKMANAGER_SUPPLICANT_SETTINGS_VERIFY_H__ +#define __NETWORKMANAGER_SUPPLICANT_SETTINGS_VERIFY_H__ typedef enum { TYPE_INVALID = 0, @@ -35,4 +35,4 @@ OptType nm_supplicant_settings_verify_setting (const char * key, const guint32 len); -#endif /* NM_SUPPLICANT_SETTINGS_VERIFY_H */ +#endif /* __NETWORKMANAGER_SUPPLICANT_SETTINGS_VERIFY_H__ */ diff --git a/src/supplicant-manager/nm-supplicant-types.h b/src/supplicant-manager/nm-supplicant-types.h index 16e4a6ba..619f0c3e 100644 --- a/src/supplicant-manager/nm-supplicant-types.h +++ b/src/supplicant-manager/nm-supplicant-types.h @@ -18,8 +18,8 @@ * Copyright (C) 2006 - 2008 Red Hat, Inc. */ -#ifndef NM_SUPPLICANT_TYPES_H -#define NM_SUPPLICANT_TYPES_H +#ifndef __NETWORKMANAGER_SUPPLICANT_TYPES_H__ +#define __NETWORKMANAGER_SUPPLICANT_TYPES_H__ typedef struct _NMSupplicantManager NMSupplicantManager; typedef struct _NMSupplicantInterface NMSupplicantInterface; diff --git a/src/supplicant-manager/tests/Makefile.am b/src/supplicant-manager/tests/Makefile.am index 9defe66b..452ccdc1 100644 --- a/src/supplicant-manager/tests/Makefile.am +++ b/src/supplicant-manager/tests/Makefile.am @@ -1,11 +1,11 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/supplicant-manager \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in index 42a7f6ff..567b6c77 100644 --- a/src/supplicant-manager/tests/Makefile.in +++ b/src/supplicant-manager/tests/Makefile.in @@ -204,6 +204,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -327,6 +329,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -346,6 +349,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -372,7 +376,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -453,12 +457,12 @@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/supplicant-manager \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c index ce884a8d..5aa3fa2d 100644 --- a/src/supplicant-manager/tests/test-supplicant-config.c +++ b/src/supplicant-manager/tests/test-supplicant-config.c @@ -18,11 +18,12 @@ * Copyright (C) 2008 - 2011 Red Hat, Inc. */ +#include "config.h" + #include #include #include #include -#include #include #include #include @@ -31,13 +32,7 @@ #include -#include -#include -#include -#include -#include -#include -#include +#include "nm-core-internal.h" #include "nm-supplicant-config.h" #include "nm-supplicant-settings-verify.h" @@ -115,19 +110,17 @@ test_wifi_open (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wifi; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSupplicantConfig *config; GHashTable *hash; char *uuid; gboolean success; GError *error = NULL; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - GByteArray *bssid; - const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; const char *bssid_str = "11:22:33:44:55:66"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -146,26 +139,22 @@ test_wifi_open (void) s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); - bssid = g_byte_array_sized_new (sizeof (bssid_data)); - g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_BSSID, bssid_str, NM_SETTING_WIRELESS_MODE, "infrastructure", NM_SETTING_WIRELESS_BAND, "bg", NULL); - g_byte_array_free (ssid, TRUE); - g_byte_array_free (bssid, TRUE); + g_bytes_unref (ssid); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, "wifi-open", "failed to verify connection: %s", @@ -216,19 +205,17 @@ test_wifi_wep_key (const char *detail, NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSupplicantConfig *config; GHashTable *hash; char *uuid; gboolean success; GError *error = NULL; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - GByteArray *bssid; - const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; const char *bssid_str = "11:22:33:44:55:66"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -247,20 +234,16 @@ test_wifi_wep_key (const char *detail, s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); - bssid = g_byte_array_sized_new (sizeof (bssid_data)); - g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_BSSID, bssid_str, NM_SETTING_WIRELESS_MODE, "infrastructure", NM_SETTING_WIRELESS_BAND, "bg", NULL); - g_byte_array_free (ssid, TRUE); - g_byte_array_free (bssid, TRUE); + g_bytes_unref (ssid); /* Wifi Security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -273,10 +256,10 @@ test_wifi_wep_key (const char *detail, nm_setting_wireless_security_set_wep_key (s_wsec, 0, key_data); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, detail, "failed to verify connection: %s", @@ -359,19 +342,17 @@ test_wifi_wpa_psk (const char *detail, NMSettingConnection *s_con; NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; NMSupplicantConfig *config; GHashTable *hash; char *uuid; gboolean success; GError *error = NULL; - GByteArray *ssid; + GBytes *ssid; const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 }; - GByteArray *bssid; - const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; const char *bssid_str = "11:22:33:44:55:66"; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Connection setting */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -390,20 +371,16 @@ test_wifi_wpa_psk (const char *detail, s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - ssid = g_byte_array_sized_new (sizeof (ssid_data)); - g_byte_array_append (ssid, ssid_data, sizeof (ssid_data)); - bssid = g_byte_array_sized_new (sizeof (bssid_data)); - g_byte_array_append (bssid, bssid_data, sizeof (bssid_data)); + ssid = g_bytes_new (ssid_data, sizeof (ssid_data)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_BSSID, bssid_str, NM_SETTING_WIRELESS_MODE, "infrastructure", NM_SETTING_WIRELESS_BAND, "bg", NULL); - g_byte_array_free (ssid, TRUE); - g_byte_array_free (bssid, TRUE); + g_bytes_unref (ssid); /* Wifi Security setting */ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -422,10 +399,10 @@ test_wifi_wpa_psk (const char *detail, nm_setting_wireless_security_add_group (s_wsec, "ccmp"); /* IP4 setting */ - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); ASSERT (nm_connection_verify (connection, &error) == TRUE, detail, "failed to verify connection: %s", diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index ee5be17d..65bc2199 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -1,38 +1,28 @@ +SUBDIRS = config + AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/dhcp-manager \ + -I$(top_srcdir)/src/devices \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) noinst_PROGRAMS = \ - test-dhcp-options \ test-general \ + test-general-with-expect \ test-ip4-config \ test-ip6-config \ test-dcb \ - test-resolvconf-capture - -####### DHCP options test ####### - -test_dhcp_options_SOURCES = \ - test-dhcp-options.c - -test_dhcp_options_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" - -test_dhcp_options_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + test-resolvconf-capture \ + test-wired-defname ####### ip4 config test ####### @@ -74,11 +64,50 @@ test_general_SOURCES = \ test_general_LDADD = \ $(top_builddir)/src/libNetworkManager.la +####### general-with-expect test ####### + +test_general_with_expect_SOURCES = \ + test-general-with-expect.c + +test_general_with_expect_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +####### wired defname test ####### + +test_wired_defname_SOURCES = \ + test-wired-defname.c + +test_wired_defname_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + ####### secret agent interface test ####### EXTRA_DIST = test-secret-agent.py ########################################### -TESTS = test-dhcp-options test-ip4-config test-ip6-config test-dcb test-resolvconf-capture test-general +TESTS = \ + test-ip4-config \ + test-ip6-config \ + test-dcb \ + test-resolvconf-capture \ + test-general \ + test-general-with-expect \ + test-wired-defname + + +if ENABLE_TESTS + +check-local: + @for t in bond bridge ethernet gre infiniband macvlan tun veth vlan vxlan; do \ + # Ensure the device subclass factory registration constructors exist \ + # which could inadvertently break if src/Makefile.am gets changed \ + if ! LC_ALL=C nm $(top_builddir)/src/NetworkManager | LC_ALL=C grep -q "register_device_factory_internal_$$t" ; then \ + echo "Testing device factory symbols... FAILED" ; \ + exit 1 ; \ + fi \ + done + @echo "Testing device factory symbols... PASSED" + +endif diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index b9af7c31..a5d5b3a8 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -78,12 +78,14 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -noinst_PROGRAMS = test-dhcp-options$(EXEEXT) test-general$(EXEEXT) \ - test-ip4-config$(EXEEXT) test-ip6-config$(EXEEXT) \ - test-dcb$(EXEEXT) test-resolvconf-capture$(EXEEXT) -TESTS = test-dhcp-options$(EXEEXT) test-ip4-config$(EXEEXT) \ +noinst_PROGRAMS = test-general$(EXEEXT) \ + test-general-with-expect$(EXEEXT) test-ip4-config$(EXEEXT) \ test-ip6-config$(EXEEXT) test-dcb$(EXEEXT) \ - test-resolvconf-capture$(EXEEXT) test-general$(EXEEXT) + test-resolvconf-capture$(EXEEXT) test-wired-defname$(EXEEXT) +TESTS = test-ip4-config$(EXEEXT) test-ip6-config$(EXEEXT) \ + test-dcb$(EXEEXT) test-resolvconf-capture$(EXEEXT) \ + test-general$(EXEEXT) test-general-with-expect$(EXEEXT) \ + test-wired-defname$(EXEEXT) subdir = src/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp @@ -115,14 +117,15 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -am_test_dhcp_options_OBJECTS = \ - test_dhcp_options-test-dhcp-options.$(OBJEXT) -test_dhcp_options_OBJECTS = $(am_test_dhcp_options_OBJECTS) -test_dhcp_options_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la am_test_general_OBJECTS = test-general.$(OBJEXT) test_general_OBJECTS = $(am_test_general_OBJECTS) test_general_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +am_test_general_with_expect_OBJECTS = \ + test-general-with-expect.$(OBJEXT) +test_general_with_expect_OBJECTS = \ + $(am_test_general_with_expect_OBJECTS) +test_general_with_expect_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la am_test_ip4_config_OBJECTS = test-ip4-config.$(OBJEXT) test_ip4_config_OBJECTS = $(am_test_ip4_config_OBJECTS) test_ip4_config_DEPENDENCIES = \ @@ -137,6 +140,10 @@ test_resolvconf_capture_OBJECTS = \ $(am_test_resolvconf_capture_OBJECTS) test_resolvconf_capture_DEPENDENCIES = \ $(top_builddir)/src/libNetworkManager.la +am_test_wired_defname_OBJECTS = test-wired-defname.$(OBJEXT) +test_wired_defname_OBJECTS = $(am_test_wired_defname_OBJECTS) +test_wired_defname_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManager.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -171,17 +178,35 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(test_dcb_SOURCES) $(test_dhcp_options_SOURCES) \ - $(test_general_SOURCES) $(test_ip4_config_SOURCES) \ - $(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) -DIST_SOURCES = $(test_dcb_SOURCES) $(test_dhcp_options_SOURCES) \ - $(test_general_SOURCES) $(test_ip4_config_SOURCES) \ - $(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) +SOURCES = $(test_dcb_SOURCES) $(test_general_SOURCES) \ + $(test_general_with_expect_SOURCES) $(test_ip4_config_SOURCES) \ + $(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) \ + $(test_wired_defname_SOURCES) +DIST_SOURCES = $(test_dcb_SOURCES) $(test_general_SOURCES) \ + $(test_general_with_expect_SOURCES) $(test_ip4_config_SOURCES) \ + $(test_ip6_config_SOURCES) $(test_resolvconf_capture_SOURCES) \ + $(test_wired_defname_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -223,7 +248,33 @@ am__tty_colors = { \ std=''; \ fi; \ } +DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" ACLOCAL = @ACLOCAL@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ @@ -233,6 +284,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -356,6 +409,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -375,6 +429,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -401,7 +456,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -480,35 +535,23 @@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ +SUBDIRS = config AM_CPPFLAGS = \ -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_builddir)/libnm-util \ - -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/dhcp-manager \ + -I$(top_srcdir)/src/devices \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) -####### DHCP options test ####### -test_dhcp_options_SOURCES = \ - test-dhcp-options.c - -test_dhcp_options_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" - -test_dhcp_options_LDADD = \ - $(top_builddir)/src/libNetworkManager.la - - ####### ip4 config test ####### test_ip4_config_SOURCES = \ test-ip4-config.c @@ -549,9 +592,25 @@ test_general_LDADD = \ $(top_builddir)/src/libNetworkManager.la +####### general-with-expect test ####### +test_general_with_expect_SOURCES = \ + test-general-with-expect.c + +test_general_with_expect_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + + +####### wired defname test ####### +test_wired_defname_SOURCES = \ + test-wired-defname.c + +test_wired_defname_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + + ####### secret agent interface test ####### EXTRA_DIST = test-secret-agent.py -all: all-am +all: all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -599,14 +658,14 @@ test-dcb$(EXEEXT): $(test_dcb_OBJECTS) $(test_dcb_DEPENDENCIES) $(EXTRA_test_dcb @rm -f test-dcb$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dcb_OBJECTS) $(test_dcb_LDADD) $(LIBS) -test-dhcp-options$(EXEEXT): $(test_dhcp_options_OBJECTS) $(test_dhcp_options_DEPENDENCIES) $(EXTRA_test_dhcp_options_DEPENDENCIES) - @rm -f test-dhcp-options$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_dhcp_options_OBJECTS) $(test_dhcp_options_LDADD) $(LIBS) - test-general$(EXEEXT): $(test_general_OBJECTS) $(test_general_DEPENDENCIES) $(EXTRA_test_general_DEPENDENCIES) @rm -f test-general$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_general_OBJECTS) $(test_general_LDADD) $(LIBS) +test-general-with-expect$(EXEEXT): $(test_general_with_expect_OBJECTS) $(test_general_with_expect_DEPENDENCIES) $(EXTRA_test_general_with_expect_DEPENDENCIES) + @rm -f test-general-with-expect$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_general_with_expect_OBJECTS) $(test_general_with_expect_LDADD) $(LIBS) + test-ip4-config$(EXEEXT): $(test_ip4_config_OBJECTS) $(test_ip4_config_DEPENDENCIES) $(EXTRA_test_ip4_config_DEPENDENCIES) @rm -f test-ip4-config$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ip4_config_OBJECTS) $(test_ip4_config_LDADD) $(LIBS) @@ -619,6 +678,10 @@ test-resolvconf-capture$(EXEEXT): $(test_resolvconf_capture_OBJECTS) $(test_reso @rm -f test-resolvconf-capture$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_resolvconf_capture_OBJECTS) $(test_resolvconf_capture_LDADD) $(LIBS) +test-wired-defname$(EXEEXT): $(test_wired_defname_OBJECTS) $(test_wired_defname_DEPENDENCIES) $(EXTRA_test_wired_defname_DEPENDENCIES) + @rm -f test-wired-defname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_wired_defname_OBJECTS) $(test_wired_defname_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -626,11 +689,12 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dcb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general-with-expect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-general.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ip4-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ip6-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-resolvconf-capture.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dhcp_options-test-dhcp-options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-wired-defname.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -653,34 +717,67 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -test_dhcp_options-test-dhcp-options.o: test-dhcp-options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_options_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dhcp_options-test-dhcp-options.o -MD -MP -MF $(DEPDIR)/test_dhcp_options-test-dhcp-options.Tpo -c -o test_dhcp_options-test-dhcp-options.o `test -f 'test-dhcp-options.c' || echo '$(srcdir)/'`test-dhcp-options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dhcp_options-test-dhcp-options.Tpo $(DEPDIR)/test_dhcp_options-test-dhcp-options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-dhcp-options.c' object='test_dhcp_options-test-dhcp-options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_options_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dhcp_options-test-dhcp-options.o `test -f 'test-dhcp-options.c' || echo '$(srcdir)/'`test-dhcp-options.c - -test_dhcp_options-test-dhcp-options.obj: test-dhcp-options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_options_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_dhcp_options-test-dhcp-options.obj -MD -MP -MF $(DEPDIR)/test_dhcp_options-test-dhcp-options.Tpo -c -o test_dhcp_options-test-dhcp-options.obj `if test -f 'test-dhcp-options.c'; then $(CYGPATH_W) 'test-dhcp-options.c'; else $(CYGPATH_W) '$(srcdir)/test-dhcp-options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dhcp_options-test-dhcp-options.Tpo $(DEPDIR)/test_dhcp_options-test-dhcp-options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-dhcp-options.c' object='test_dhcp_options-test-dhcp-options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dhcp_options_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_dhcp_options-test-dhcp-options.obj `if test -f 'test-dhcp-options.c'; then $(CYGPATH_W) 'test-dhcp-options.c'; else $(CYGPATH_W) '$(srcdir)/test-dhcp-options.c'; fi` - mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am +tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ @@ -693,7 +790,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $$unique; \ fi; \ fi -ctags: ctags-am +ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) @@ -706,7 +803,7 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am +cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ @@ -848,20 +945,47 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local +check: check-recursive all-am: Makefile $(PROGRAMS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ @@ -883,94 +1007,106 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -clean: clean-am +clean: clean-recursive clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: -.MAKE: check-am install-am install-strip +.MAKE: $(am__recursive_targets) check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ - clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ - ctags ctags-am distclean distclean-compile distclean-generic \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-TESTS check-am check-local clean clean-generic \ + clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ + installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am +@ENABLE_TESTS_TRUE@check-local: +@ENABLE_TESTS_TRUE@ @for t in bond bridge ethernet gre infiniband macvlan tun veth vlan vxlan; do \ +@ENABLE_TESTS_TRUE@ # Ensure the device subclass factory registration constructors exist \ +@ENABLE_TESTS_TRUE@ # which could inadvertently break if src/Makefile.am gets changed \ +@ENABLE_TESTS_TRUE@ if ! LC_ALL=C nm $(top_builddir)/src/NetworkManager | LC_ALL=C grep -q "register_device_factory_internal_$$t" ; then \ +@ENABLE_TESTS_TRUE@ echo "Testing device factory symbols... FAILED" ; \ +@ENABLE_TESTS_TRUE@ exit 1 ; \ +@ENABLE_TESTS_TRUE@ fi \ +@ENABLE_TESTS_TRUE@ done +@ENABLE_TESTS_TRUE@ @echo "Testing device factory symbols... PASSED" + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/tests/config/Makefile.am b/src/tests/config/Makefile.am new file mode 100644 index 00000000..66009c87 --- /dev/null +++ b/src/tests/config/Makefile.am @@ -0,0 +1,33 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/src/ \ + -I$(top_srcdir)/src/devices \ + -I${top_srcdir}/src/platform \ + -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSRCDIR=\""$(srcdir)"\" + +noinst_PROGRAMS = \ + test-config + +test_config_SOURCES = \ + nm-test-device.c \ + nm-test-device.h \ + test-config.c + +test_config_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +TESTS = test-config + +EXTRA_DIST = \ + NetworkManager.conf \ + bad.conf \ + conf.d/00-overrides.conf \ + conf.d/10-more.conf \ + conf.d/90-last.conf diff --git a/src/tests/config/Makefile.in b/src/tests/config/Makefile.in new file mode 100644 index 00000000..81fb0885 --- /dev/null +++ b/src/tests/config/Makefile.in @@ -0,0 +1,871 @@ +# Makefile.in generated by automake 1.13.4 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = test-config$(EXEEXT) +TESTS = test-config$(EXEEXT) +subdir = src/tests/config +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/build-aux/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ + $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gnome-code-coverage.m4 \ + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/introspection.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/m4/vapigen.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_test_config_OBJECTS = nm-test-device.$(OBJEXT) \ + test-config.$(OBJEXT) +test_config_OBJECTS = $(am_test_config_OBJECTS) +test_config_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(test_config_SOURCES) +DIST_SOURCES = $(test_config_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CKDB_PATH = @CKDB_PATH@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ +DBUS_LIBS = @DBUS_LIBS@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DHCLIENT_PATH = @DHCLIENT_PATH@ +DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ +DLLTOOL = @DLLTOOL@ +DNSMASQ_PATH = @DNSMASQ_PATH@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MAKEFILE = @GLIB_MAKEFILE@ +GLIB_MKENUMS = @GLIB_MKENUMS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GUDEV_CFLAGS = @GUDEV_CFLAGS@ +GUDEV_LIBS = @GUDEV_LIBS@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +IPTABLES_PATH = @IPTABLES_PATH@ +IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ +IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ +KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBDL = @LIBDL@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ +LIBNL_CFLAGS = @LIBNL_CFLAGS@ +LIBNL_LIBS = @LIBNL_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ +LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MM_GLIB_CFLAGS = @MM_GLIB_CFLAGS@ +MM_GLIB_LIBS = @MM_GLIB_LIBS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ +NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ +NM_MICRO_VERSION = @NM_MICRO_VERSION@ +NM_MINOR_VERSION = @NM_MINOR_VERSION@ +NM_MODIFY_SYSTEM_POLICY = @NM_MODIFY_SYSTEM_POLICY@ +NM_VERSION = @NM_VERSION@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ +PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ +QT_CFLAGS = @QT_CFLAGS@ +QT_LIBS = @QT_LIBS@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_200_CFLAGS = @SYSTEMD_200_CFLAGS@ +SYSTEMD_200_LIBS = @SYSTEMD_200_LIBS@ +SYSTEMD_INHIBIT_CFLAGS = @SYSTEMD_INHIBIT_CFLAGS@ +SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ +SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ +SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ +SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ +UDEV_DIR = @UDEV_DIR@ +USE_NLS = @USE_NLS@ +UUID_CFLAGS = @UUID_CFLAGS@ +UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ +VAPIGEN = @VAPIGEN@ +VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ +VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +nmbinary = @nmbinary@ +nmconfdir = @nmconfdir@ +nmdatadir = @nmdatadir@ +nmrundir = @nmrundir@ +nmstatedir = @nmstatedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +with_dhclient = @with_dhclient@ +with_dhcpcd = @with_dhcpcd@ +with_netconfig = @with_netconfig@ +with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-core \ + -I$(top_builddir)/libnm-core \ + -I$(top_srcdir)/src/ \ + -I$(top_srcdir)/src/devices \ + -I${top_srcdir}/src/platform \ + -DG_LOG_DOMAIN=\""NetworkManager"\" \ + -DNETWORKMANAGER_COMPILATION \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + -DSRCDIR=\""$(srcdir)"\" + +test_config_SOURCES = \ + nm-test-device.c \ + nm-test-device.h \ + test-config.c + +test_config_LDADD = \ + $(top_builddir)/src/libNetworkManager.la + +EXTRA_DIST = \ + NetworkManager.conf \ + bad.conf \ + conf.d/00-overrides.conf \ + conf.d/10-more.conf \ + conf.d/90-last.conf + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/tests/config/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/tests/config/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +test-config$(EXEEXT): $(test_config_OBJECTS) $(test_config_DEPENDENCIES) $(EXTRA_test_config_DEPENDENCIES) + @rm -f test-config$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_config_OBJECTS) $(test_config_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-test-device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-config.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/tests/config/NetworkManager.conf b/src/tests/config/NetworkManager.conf new file mode 100644 index 00000000..401ba48a --- /dev/null +++ b/src/tests/config/NetworkManager.conf @@ -0,0 +1,15 @@ +[main] +dhcp=dhclient +plugins=foo,bar,baz +no-auto-default=11:11:11:11:11:11 + +[logging] +level=INFO + +[connectivity] +uri=http://example.com +interval=100 +response=Hello + +[extra-section] +extra-key=some value diff --git a/src/tests/config/bad.conf b/src/tests/config/bad.conf new file mode 100644 index 00000000..20d6a67a --- /dev/null +++ b/src/tests/config/bad.conf @@ -0,0 +1 @@ +This is not a keyfile. diff --git a/src/tests/config/conf.d/00-overrides.conf b/src/tests/config/conf.d/00-overrides.conf new file mode 100644 index 00000000..0aa19d48 --- /dev/null +++ b/src/tests/config/conf.d/00-overrides.conf @@ -0,0 +1,11 @@ +[main] +dhcp=dhcpcd + +[logging] +domains=PLATFORM,DNS,WIFI + +[order] +a=0 +b=0 +c=0 + diff --git a/src/tests/config/conf.d/10-more.conf b/src/tests/config/conf.d/10-more.conf new file mode 100644 index 00000000..b1424a4b --- /dev/null +++ b/src/tests/config/conf.d/10-more.conf @@ -0,0 +1,11 @@ +[main] +extra=hello +new+=something + +[connectivity] +uri=http://example.net + +[order] +a=10 +b=10 + diff --git a/src/tests/config/conf.d/90-last.conf b/src/tests/config/conf.d/90-last.conf new file mode 100644 index 00000000..dc1de394 --- /dev/null +++ b/src/tests/config/conf.d/90-last.conf @@ -0,0 +1,5 @@ +[main] +plugins+=one,two + +[order] +a=90 diff --git a/src/tests/config/nm-test-device.c b/src/tests/config/nm-test-device.c new file mode 100644 index 00000000..63067b25 --- /dev/null +++ b/src/tests/config/nm-test-device.c @@ -0,0 +1,99 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-test-device.h" +#include "nm-device-private.h" +#include "nm-utils.h" + +static GObjectClass *g_object_class; + +G_DEFINE_TYPE (NMTestDevice, nm_test_device, NM_TYPE_DEVICE) + +static void +nm_test_device_init (NMTestDevice *self) +{ +} + +/* We jump over NMDevice's construct/destruct methods, which require NMPlatform + * and NMConnectionProvider to be initialized. + */ + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + return g_object_class->constructor (type, + n_construct_params, + construct_params); +} + +static void +constructed (GObject *object) +{ + g_object_class->constructed (object); +} + +static void +dispose (GObject *object) +{ + g_object_class->dispose (object); +} + +static void +finalize (GObject *object) +{ + g_object_class->finalize (object); +} + +static guint32 +get_generic_capabilities (NMDevice *device) +{ + return NM_DEVICE_CAP_IS_NON_KERNEL; +} + +static void +nm_test_device_class_init (NMTestDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + g_object_class = g_type_class_peek (G_TYPE_OBJECT); + + object_class->constructor = constructor; + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->finalize = finalize; + + device_class->get_generic_capabilities = get_generic_capabilities; +} + +NMDevice * +nm_test_device_new (const char *hwaddr) +{ + return g_object_new (NM_TYPE_TEST_DEVICE, + NM_DEVICE_IFACE, "dummy", + NM_DEVICE_HW_ADDRESS, hwaddr, + NULL); +} diff --git a/src/tests/config/nm-test-device.h b/src/tests/config/nm-test-device.h new file mode 100644 index 00000000..00b21c42 --- /dev/null +++ b/src/tests/config/nm-test-device.h @@ -0,0 +1,50 @@ +/* -*- 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 + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_TEST_DEVICE_H__ +#define __NETWORKMANAGER_TEST_DEVICE_H__ + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_TEST_DEVICE (nm_test_device_get_type ()) +#define NM_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_TEST_DEVICE, NMTestDevice)) +#define NM_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) +#define NM_IS_TEST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_TEST_DEVICE)) +#define NM_IS_TEST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_TEST_DEVICE)) +#define NM_TEST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_TEST_DEVICE, NMTestDeviceClass)) + +typedef struct { + NMDevice parent; + +} NMTestDevice; + +typedef struct { + NMDeviceClass parent; +} NMTestDeviceClass; + +GType nm_test_device_get_type (void); + +NMDevice *nm_test_device_new (const char *hwaddr); + +G_END_DECLS + +#endif /* NM_DEVICE_H */ diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c new file mode 100644 index 00000000..808fc670 --- /dev/null +++ b/src/tests/config/test-config.c @@ -0,0 +1,308 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2013 Red Hat, Inc. + * + */ + +#include "config.h" + +#include + +#include + +#include +#include "nm-test-device.h" +#include "nm-fake-platform.h" + +static void +setup_config (const char *config_file, const char *config_dir, ...) +{ + va_list ap; + GPtrArray *args; + char **argv, *arg; + int argc; + GOptionContext *context; + gboolean success; + + args = g_ptr_array_new (); + g_ptr_array_add (args, "test-config"); + g_ptr_array_add (args, "--config"); + g_ptr_array_add (args, (char *)config_file); + g_ptr_array_add (args, "--config-dir"); + g_ptr_array_add (args, (char *)config_dir); + + va_start (ap, config_dir); + while ((arg = va_arg (ap, char *))) + g_ptr_array_add (args, arg); + va_end (ap); + + argv = (char **)args->pdata; + argc = args->len; + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, nm_config_get_options (), NULL); + success = g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + + if (!success) + g_printerr ("Invalid options.\n"); + + g_ptr_array_free (args, TRUE); +} + +static void +test_config_simple (void) +{ + NMConfig *config; + GError *error = NULL; + const char **plugins; + char *value; + + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); + g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient"); + g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); + g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100); + + plugins = nm_config_get_plugins (config); + g_assert_cmpint (g_strv_length ((char **)plugins), ==, 3); + g_assert_cmpstr (plugins[0], ==, "foo"); + g_assert_cmpstr (plugins[1], ==, "bar"); + g_assert_cmpstr (plugins[2], ==, "baz"); + + value = nm_config_get_value (config, "extra-section", "extra-key", NULL); + g_assert_cmpstr (value, ==, "some value"); + g_free (value); + + value = nm_config_get_value (config, "extra-section", "no-key", &error); + g_assert (!value); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND); + g_clear_error (&error); + + value = nm_config_get_value (config, "no-section", "no-key", &error); + g_assert (!value); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_clear_error (&error); + + g_object_unref (config); +} + +static void +test_config_non_existent (void) +{ + NMConfig *config; + GError *error = NULL; + + setup_config (SRCDIR "/no-such-file", "/no/such/dir", NULL); + config = nm_config_new (&error); + g_assert (!config); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND); +} + +static void +test_config_parse_error (void) +{ + NMConfig *config; + GError *error = NULL; + + setup_config (SRCDIR "/bad.conf", "/no/such/dir", NULL); + config = nm_config_new (&error); + g_assert (!config); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); +} + +static void +test_config_override (void) +{ + NMConfig *config; + GError *error = NULL; + const char **plugins; + + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", + "--plugins", "alpha,beta,gamma,delta", + "--connectivity-interval", "12", + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); + g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhclient"); + g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); + g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 12); + + plugins = nm_config_get_plugins (config); + g_assert_cmpint (g_strv_length ((char **)plugins), ==, 4); + g_assert_cmpstr (plugins[0], ==, "alpha"); + g_assert_cmpstr (plugins[1], ==, "beta"); + g_assert_cmpstr (plugins[2], ==, "gamma"); + g_assert_cmpstr (plugins[3], ==, "delta"); + + g_object_unref (config); +} + +static void +test_config_no_auto_default (void) +{ + NMConfig *config; + GError *error = NULL; + int fd, nwrote; + char *state_file; + NMDevice *dev1, *dev2, *dev3, *dev4; + + fd = g_file_open_tmp (NULL, &state_file, &error); + g_assert_no_error (error); + + nwrote = write (fd, "22:22:22:22:22:22\n", 18); + g_assert_cmpint (nwrote, ==, 18); + nwrote = write (fd, "44:44:44:44:44:44\n", 18); + g_assert_cmpint (nwrote, ==, 18); + close (fd); + + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + dev1 = nm_test_device_new ("11:11:11:11:11:11"); + dev2 = nm_test_device_new ("22:22:22:22:22:22"); + dev3 = nm_test_device_new ("33:33:33:33:33:33"); + dev4 = nm_test_device_new ("44:44:44:44:44:44"); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2)); + g_assert (nm_config_get_ethernet_can_auto_default (config, dev3)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4)); + + nm_config_set_ethernet_no_auto_default (config, dev3); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3)); + + g_object_unref (config); + + setup_config (SRCDIR "/NetworkManager.conf", "/no/such/dir", + "--no-auto-default", state_file, + NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev1)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev2)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev3)); + g_assert (!nm_config_get_ethernet_can_auto_default (config, dev4)); + + g_object_unref (config); + + g_object_unref (dev1); + g_object_unref (dev2); + g_object_unref (dev3); + g_object_unref (dev4); + + unlink (state_file); + g_free (state_file); +} + +static void +test_config_confdir (void) +{ + NMConfig *config; + GError *error = NULL; + const char **plugins; + char *value; + + setup_config (SRCDIR "/NetworkManager.conf", SRCDIR "/conf.d", NULL); + config = nm_config_new (&error); + g_assert_no_error (error); + + g_assert_cmpstr (nm_config_get_path (config), ==, SRCDIR "/NetworkManager.conf"); + g_assert_cmpstr (nm_config_get_dhcp_client (config), ==, "dhcpcd"); + g_assert_cmpstr (nm_config_get_log_level (config), ==, "INFO"); + g_assert_cmpstr (nm_config_get_log_domains (config), ==, "PLATFORM,DNS,WIFI"); + g_assert_cmpstr (nm_config_get_connectivity_uri (config), ==, "http://example.net"); + g_assert_cmpint (nm_config_get_connectivity_interval (config), ==, 100); + + plugins = nm_config_get_plugins (config); + g_assert_cmpint (g_strv_length ((char **)plugins), ==, 5); + g_assert_cmpstr (plugins[0], ==, "foo"); + g_assert_cmpstr (plugins[1], ==, "bar"); + g_assert_cmpstr (plugins[2], ==, "baz"); + g_assert_cmpstr (plugins[3], ==, "one"); + g_assert_cmpstr (plugins[4], ==, "two"); + + value = nm_config_get_value (config, "main", "extra", NULL); + g_assert_cmpstr (value, ==, "hello"); + g_free (value); + + value = nm_config_get_value (config, "main", "new", NULL); + g_assert_cmpstr (value, ==, "something"); /* not ",something" */ + g_free (value); + + value = nm_config_get_value (config, "order", "a", NULL); + g_assert_cmpstr (value, ==, "90"); + g_free (value); + value = nm_config_get_value (config, "order", "b", NULL); + g_assert_cmpstr (value, ==, "10"); + g_free (value); + value = nm_config_get_value (config, "order", "c", NULL); + g_assert_cmpstr (value, ==, "0"); + g_free (value); + + g_object_unref (config); +} + +static void +test_config_confdir_parse_error (void) +{ + NMConfig *config; + GError *error = NULL; + + /* Using SRCDIR as the conf dir will pick up bad.conf */ + setup_config (SRCDIR "/NetworkManager.conf", SRCDIR, NULL); + config = nm_config_new (&error); + g_assert (!config); + g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE); +} + +int +main (int argc, char **argv) +{ +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + g_test_init (&argc, &argv, NULL); + + nm_fake_platform_setup (); + + g_test_add_func ("/config/simple", test_config_simple); + g_test_add_func ("/config/non-existent", test_config_non_existent); + g_test_add_func ("/config/parse-error", test_config_parse_error); + g_test_add_func ("/config/no-auto-default", test_config_no_auto_default); + g_test_add_func ("/config/confdir", test_config_confdir); + g_test_add_func ("/config/confdir-parse-error", test_config_confdir_parse_error); + + /* 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. + */ + g_test_add_func ("/config/override", test_config_override); + + return g_test_run (); +} + diff --git a/src/tests/test-dcb.c b/src/tests/test-dcb.c index c28f05b9..dacb1f52 100644 --- a/src/tests/test-dcb.c +++ b/src/tests/test-dcb.c @@ -18,6 +18,8 @@ * */ +#include "config.h" + #include #include diff --git a/src/tests/test-dhcp-options.c b/src/tests/test-dhcp-options.c deleted file mode 100644 index 5df17e58..00000000 --- a/src/tests/test-dhcp-options.c +++ /dev/null @@ -1,937 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-dhcp-manager.c - Handle the DHCP daemon for NetworkManager - * - * 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, 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 - 2011 Red Hat, Inc. - * - */ - -#include -#include -#include -#include -#include - -#include - -#include "nm-dhcp-manager.h" -#include "nm-logging.h" - -#include "nm-test-utils.h" - -typedef struct { - const char *name; - const char *value; -} Option; - -static void -destroy_gvalue (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static GValue * -string_to_byte_array_gvalue (const char *str) -{ - GByteArray *array; - GValue *val; - - array = g_byte_array_sized_new (strlen (str)); - g_byte_array_append (array, (const guint8 *) str, strlen (str)); - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_take_boxed (val, array); - - return val; -} - -static GHashTable * -fill_table (Option *test_options, GHashTable *table) -{ - Option *opt; - - if (!table) - table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue); - for (opt = test_options; opt->name; opt++) { - g_hash_table_insert (table, - (gpointer) opt->name, - string_to_byte_array_gvalue (opt->value)); - } - return table; -} - -static Option generic_options[] = { - { "new_subnet_mask", "255.255.255.0" }, - { "new_ip_address", "192.168.1.106" }, - { "new_network_number", "192.168.1.0" }, - { "interface", "eth0" }, - { "reason", "BOUND" }, - { "new_expiry", "1232324877" }, - { "new_dhcp_lease_time", "3600" }, - { "new_dhcp_server_identifier", "192.168.1.1" }, - { "new_routers", "192.168.1.1" }, - { "new_domain_name_servers", "216.254.95.2 216.231.41.2" }, - { "new_dhcp_message_type", "5" }, - { "new_broadcast_address", "192.168.1.255" }, - { "new_domain_search", "foobar.com blah.foobar.com" }, - { "new_host_name", "nmreallywhipsthe" }, - { "new_domain_name", "lamasass.com" }, - { "new_interface_mtu", "987" }, - { "new_static_routes", "10.1.1.5 10.1.1.1 100.99.88.56 10.1.1.1" }, - { NULL, NULL } -}; - -static void -test_generic_options (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const NMPlatformIP4Address *address; - const NMPlatformIP4Route *route; - guint32 tmp; - const char *expected_addr = "192.168.1.106"; - const char *expected_gw = "192.168.1.1"; - const char *expected_dns1 = "216.254.95.2"; - const char *expected_dns2 = "216.231.41.2"; - const char *expected_search1 = "foobar.com"; - const char *expected_search2 = "blah.foobar.com"; - const char *expected_route1_dest = "10.1.1.5"; - const char *expected_route1_gw = "10.1.1.1"; - const char *expected_route2_dest = "100.99.88.56"; - const char *expected_route2_gw = "10.1.1.1"; - - options = fill_table (generic_options, NULL); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-generic", "failed to parse DHCP4 options"); - - /* IP4 address */ - ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, - "dhcp-generic", "unexpected number of IP addresses"); - address = nm_ip4_config_get_address (ip4_config, 0); - - ASSERT (inet_pton (AF_INET, expected_addr, &tmp) > 0, - "dhcp-generic", "couldn't convert expected IP address"); - ASSERT (address->address == tmp, - "dhcp-generic", "unexpected IP address"); - ASSERT (address->peer_address == 0, - "dhcp-generic", "unexpected PTP address"); - - ASSERT (address->plen == 24, - "dhcp-generic", "unexpected IP address prefix length"); - - /* Gateway */ - ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0, - "dhcp-generic", "couldn't convert expected IP gateway"); - ASSERT (nm_ip4_config_get_gateway (ip4_config) == tmp, - "dhcp-generic", "unexpected IP gateway"); - - ASSERT (nm_ip4_config_get_num_wins (ip4_config) == 0, - "dhcp-generic", "unexpected number of WINS servers"); - - ASSERT (nm_ip4_config_get_mtu (ip4_config) == 987, - "dhcp-generic", "unexpected MTU"); - - /* Domain searches */ - ASSERT (nm_ip4_config_get_num_searches (ip4_config) == 2, - "dhcp-generic", "unexpected number of domain searches"); - ASSERT (strcmp (nm_ip4_config_get_search (ip4_config, 0), expected_search1) == 0, - "dhcp-generic", "unexpected domain search #1"); - ASSERT (strcmp (nm_ip4_config_get_search (ip4_config, 1), expected_search2) == 0, - "dhcp-generic", "unexpected domain search #2"); - - /* DNS servers */ - ASSERT (nm_ip4_config_get_num_nameservers (ip4_config) == 2, - "dhcp-generic", "unexpected number of domain name servers"); - ASSERT (inet_pton (AF_INET, expected_dns1, &tmp) > 0, - "dhcp-generic", "couldn't convert expected DNS server address #1"); - ASSERT (nm_ip4_config_get_nameserver (ip4_config, 0) == tmp, - "dhcp-generic", "unexpected domain name server #1"); - ASSERT (inet_pton (AF_INET, expected_dns2, &tmp) > 0, - "dhcp-generic", "couldn't convert expected DNS server address #2"); - ASSERT (nm_ip4_config_get_nameserver (ip4_config, 1) == tmp, - "dhcp-generic", "unexpected domain name server #2"); - - /* Routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-generic", "unexpected number of routes"); - - /* Route #1 */ - route = nm_ip4_config_get_route (ip4_config, 0); - ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0, - "dhcp-generic", "couldn't convert expected route destination #1"); - ASSERT (route->network == tmp, - "dhcp-generic", "unexpected route #1 destination"); - - ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0, - "dhcp-generic", "couldn't convert expected route next hop #1"); - ASSERT (route->gateway == tmp, - "dhcp-generic", "unexpected route #1 next hop"); - - ASSERT (route->plen == 32, - "dhcp-generic", "unexpected route #1 prefix"); - ASSERT (route->metric == 0, - "dhcp-generic", "unexpected route #1 metric"); - - /* Route #2 */ - route = nm_ip4_config_get_route (ip4_config, 1); - ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0, - "dhcp-generic", "couldn't convert expected route destination #2"); - ASSERT (route->network == tmp, - "dhcp-generic", "unexpected route #2 destination"); - - ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0, - "dhcp-generic", "couldn't convert expected route next hop #2"); - ASSERT (route->gateway == tmp, - "dhcp-generic", "unexpected route #2 next hop"); - - ASSERT (route->plen == 32, - "dhcp-generic", "unexpected route #2 prefix"); - ASSERT (route->metric == 0, - "dhcp-generic", "unexpected route #2 metric"); - - g_hash_table_destroy (options); -} - -static Option wins_options[] = { - { "new_netbios_name_servers", "63.12.199.5 150.4.88.120" }, - { NULL, NULL } -}; - -static void -test_wins_options (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const NMPlatformIP4Address *address; - guint32 tmp; - const char *expected_wins1 = "63.12.199.5"; - const char *expected_wins2 = "150.4.88.120"; - - options = fill_table (generic_options, NULL); - options = fill_table (wins_options, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-wins", "failed to parse DHCP4 options"); - - /* IP4 address */ - ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, - "dhcp-wins", "unexpected number of IP addresses"); - address = nm_ip4_config_get_address (ip4_config, 0); - ASSERT (address != NULL, "dhcp-wins", "unexpectedly did not get address #0"); - - ASSERT (nm_ip4_config_get_num_wins (ip4_config) == 2, - "dhcp-wins", "unexpected number of WINS servers"); - ASSERT (inet_pton (AF_INET, expected_wins1, &tmp) > 0, - "dhcp-wins", "couldn't convert expected WINS server address #1"); - ASSERT (nm_ip4_config_get_wins (ip4_config, 0) == tmp, - "dhcp-wins", "unexpected WINS server #1"); - ASSERT (inet_pton (AF_INET, expected_wins2, &tmp) > 0, - "dhcp-wins", "couldn't convert expected WINS server address #1"); - ASSERT (nm_ip4_config_get_wins (ip4_config, 1) == tmp, - "dhcp-wins", "unexpected WINS server #1"); - - g_hash_table_destroy (options); -} - -static void -ip4_test_route (const char *test, - NMIP4Config *ip4_config, - guint route_num, - const char *expected_dest, - const char *expected_gw, - guint expected_prefix) -{ - const NMPlatformIP4Route *route; - guint32 tmp; - - route = nm_ip4_config_get_route (ip4_config, route_num); - ASSERT (inet_pton (AF_INET, expected_dest, &tmp) > 0, - test, "couldn't convert expected route destination #1"); - ASSERT (route->network == tmp, - test, "unexpected route %d destination", route_num + 1); - - ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0, - test, "couldn't convert expected route next hop %d", - route_num + 1); - ASSERT (route->gateway == tmp, - test, "unexpected route %d next hop", route_num + 1); - - ASSERT (route->plen == expected_prefix, - test, "unexpected route %d prefix", route_num + 1); - ASSERT (route->metric == 0, - test, "unexpected route %d metric", route_num + 1); -} - -static void -ip4_test_gateway (const char *test, - NMIP4Config *ip4_config, - const char *expected_gw) -{ - guint32 tmp; - - ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, - test, "unexpected number of IP addresses"); - ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0, - test, "couldn't convert expected IP gateway"); - ASSERT (nm_ip4_config_get_gateway (ip4_config) == tmp, - test, "unexpected IP gateway"); -} - -static void -test_classless_static_routes_1 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - const char *expected_route2_dest = "10.0.0.0"; - const char *expected_route2_gw = "10.17.66.41"; - static Option data[] = { - /* dhclient custom format */ - { "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-classless-1", "failed to parse DHCP4 options"); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-classless-1", "unexpected number of IP routes"); - ip4_test_route ("dhcp-classless-1", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - ip4_test_route ("dhcp-classless-1", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 8); - - g_hash_table_destroy (options); -} - -static void -test_classless_static_routes_2 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - const char *expected_route2_dest = "10.0.0.0"; - const char *expected_route2_gw = "10.17.66.41"; - static Option data[] = { - /* dhcpcd format */ - { "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-classless-2", "failed to parse DHCP4 options"); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-classless-2", "unexpected number of IP routes"); - ip4_test_route ("dhcp-classless-2", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - ip4_test_route ("dhcp-classless-2", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 8); - - g_hash_table_destroy (options); -} - -static void -test_fedora_dhclient_classless_static_routes (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "129.210.177.128"; - const char *expected_route1_gw = "192.168.0.113"; - const char *expected_route2_dest = "2.0.0.0"; - const char *expected_route2_gw = "10.34.255.6"; - const char *expected_gateway = "192.168.0.113"; - static Option data[] = { - /* Fedora dhclient format */ - { "new_classless_static_routes", "0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-fedora-dhclient-classless", "failed to parse DHCP4 options"); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-fedora-dhclient-classless", "unexpected number of IP routes"); - ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 25); - ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 7); - - /* Gateway */ - ip4_test_gateway ("dhcp-fedora-dhclient-classless", ip4_config, expected_gateway); - - g_hash_table_destroy (options); -} - -static void -test_dhclient_invalid_classless_routes_1 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - static Option data[] = { - /* dhclient format */ - { "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring invalid classless static routes*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhclient-classless-invalid-1", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, - "dhcp-dhclient-classless-invalid-1", "unexpected number of IP routes"); - - ip4_test_route ("dhcp-dhclient-classless-invalid-1", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - - g_hash_table_destroy (options); -} - -static void -test_dhcpcd_invalid_classless_routes_1 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "10.1.1.5"; - const char *expected_route1_gw = "10.1.1.1"; - const char *expected_route2_dest = "100.99.88.56"; - const char *expected_route2_gw = "10.1.1.1"; - static Option data[] = { - /* dhcpcd format */ - { "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring invalid classless static routes*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhcpcd-classless-invalid-1", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* Test falling back to old-style static routes if the classless static - * routes are invalid. - */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-dhcpcdp-classless-invalid-1", "unexpected number of routes"); - ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 32); - ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 32); - - g_hash_table_destroy (options); -} - -static void -test_dhclient_invalid_classless_routes_2 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "10.1.1.5"; - const char *expected_route1_gw = "10.1.1.1"; - const char *expected_route2_dest = "100.99.88.56"; - const char *expected_route2_gw = "10.1.1.1"; - static Option data[] = { - { "new_rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring invalid classless static routes*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhclient-classless-invalid-2", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* Test falling back to old-style static routes if the classless static - * routes are invalid. - */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-dhclient-classless-invalid-2", "unexpected number of routes"); - ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 32); - ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 32); - - g_hash_table_destroy (options); -} - -static void -test_dhcpcd_invalid_classless_routes_2 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "10.1.1.5"; - const char *expected_route1_gw = "10.1.1.1"; - const char *expected_route2_dest = "100.99.88.56"; - const char *expected_route2_gw = "10.1.1.1"; - static Option data[] = { - { "new_classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring invalid classless static routes*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhcpcd-classless-invalid-2", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* Test falling back to old-style static routes if the classless static - * routes are invalid. - */ - - /* Routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2, - "dhcp-dhcpcd-classless-invalid-2", "unexpected number of routes"); - ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 32); - ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 1, - expected_route2_dest, expected_route2_gw, 32); - - g_hash_table_destroy (options); -} - -static void -test_dhclient_invalid_classless_routes_3 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - static Option data[] = { - { "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*ignoring invalid classless static routes*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhclient-classless-invalid-3", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, - "dhcp-dhclient-classless-invalid-3", "unexpected number of IP routes"); - ip4_test_route ("dhcp-dhclient-classless-invalid-3", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - - g_hash_table_destroy (options); -} - -static void -test_dhcpcd_invalid_classless_routes_3 (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - static Option data[] = { - { "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*DHCP provided invalid classless static route*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhcpcd-classless-invalid-3", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, - "dhcp-dhcpcd-classless-invalid-3", "unexpected number of IP routes"); - ip4_test_route ("dhcp-dhcpcd-classless-invalid-3", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - - g_hash_table_destroy (options); -} - -static void -test_dhclient_gw_in_classless_routes (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - const char *expected_gateway = "192.2.3.4"; - static Option data[] = { - { "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhclient-classless-gateway", "failed to parse DHCP4 options"); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, - "dhcp-dhclient-classless-gateway", "unexpected number of IP routes"); - ip4_test_route ("dhcp-dhclient-classless-gateway", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - - /* Gateway */ - ip4_test_gateway ("dhcp-dhclient-classless-gateway", ip4_config, expected_gateway); - - g_hash_table_destroy (options); -} - -static void -test_dhcpcd_gw_in_classless_routes (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_route1_dest = "192.168.10.0"; - const char *expected_route1_gw = "192.168.1.1"; - const char *expected_gateway = "192.2.3.4"; - static Option data[] = { - { "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" }, - { NULL, NULL } - }; - - options = fill_table (generic_options, NULL); - options = fill_table (data, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-dhcpcd-classless-gateway", "failed to parse DHCP4 options"); - - /* IP4 routes */ - ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1, - "dhcp-dhcpcd-classless-gateway", "unexpected number of IP routes"); - ip4_test_route ("dhcp-dhcpcd-classless-gateway", ip4_config, 0, - expected_route1_dest, expected_route1_gw, 24); - - /* Gateway */ - ip4_test_gateway ("dhcp-dhcpcd-classless-gateway", ip4_config, expected_gateway); - - g_hash_table_destroy (options); -} - -static Option escaped_searches_options[] = { - { "new_domain_search", "host1\\032host2\\032host3" }, - { NULL, NULL } -}; - -static void -test_escaped_domain_searches (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const char *expected_search0 = "host1"; - const char *expected_search1 = "host2"; - const char *expected_search2 = "host3"; - - options = fill_table (generic_options, NULL); - options = fill_table (escaped_searches_options, options); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-escaped-domain-searches", "failed to parse DHCP4 options"); - - /* domain searches */ - ASSERT (nm_ip4_config_get_num_searches (ip4_config) == 3, - "dhcp-escaped-domain-searches", "unexpected number of searches"); - ASSERT (!strcmp (nm_ip4_config_get_search (ip4_config, 0), expected_search0), - "dhcp-escaped-domain-searches", "unexpected domain search #1"); - ASSERT (!strcmp (nm_ip4_config_get_search (ip4_config, 1), expected_search1), - "dhcp-escaped-domain-searches", "unexpected domain search #1"); - ASSERT (!strcmp (nm_ip4_config_get_search (ip4_config, 2), expected_search2), - "dhcp-escaped-domain-searches", "unexpected domain search #1"); - - g_hash_table_destroy (options); -} - -static Option invalid_escaped_searches_options[] = { - { "new_domain_search", "host1\\aahost2\\032host3" }, - { NULL, NULL } -}; - -static void -test_invalid_escaped_domain_searches (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - - options = fill_table (generic_options, NULL); - options = fill_table (invalid_escaped_searches_options, options); - - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, - "*invalid domain search*"); - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-invalid-escaped-domain-searches", "failed to parse DHCP4 options"); - g_test_assert_expected_messages (); - - /* domain searches */ - ASSERT (nm_ip4_config_get_num_searches (ip4_config) == 0, - "dhcp-invalid-escaped-domain-searches", "unexpected domain searches"); - - g_hash_table_destroy (options); -} - -static void -test_ip4_missing_prefix (const char *client, const char *ip, guint32 expected_prefix) -{ - GHashTable *options; - NMIP4Config *ip4_config; - const NMPlatformIP4Address *address; - - options = fill_table (generic_options, NULL); - g_hash_table_insert (options, "new_ip_address", string_to_byte_array_gvalue (ip)); - g_hash_table_remove (options, "new_subnet_mask"); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-ip4-missing-prefix", "failed to parse DHCP4 options"); - - ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, - "dhcp-ip4-missing-prefix", "unexpected number of IP4 addresses (not 1)"); - - address = nm_ip4_config_get_address (ip4_config, 0); - ASSERT (address, - "dhcp-ip4-missing-prefix", "missing IP4 address #1"); - - ASSERT (address->plen == expected_prefix, - "dhcp-ip4-missing-prefix", "unexpected IP4 address prefix %d (expected %d)", - address->plen, expected_prefix); - - g_hash_table_destroy (options); -} - -static void -test_ip4_missing_prefix_24 (gconstpointer test_data) -{ - const char *client = test_data; - - test_ip4_missing_prefix (client, "192.168.1.10", 24); -} - -static void -test_ip4_missing_prefix_16 (gconstpointer test_data) -{ - const char *client = test_data; - - test_ip4_missing_prefix (client, "172.16.54.50", 16); -} - -static void -test_ip4_missing_prefix_8 (gconstpointer test_data) -{ - const char *client = test_data; - - test_ip4_missing_prefix (client, "10.1.2.3", 8); -} - -static void -test_ip4_prefix_classless (gconstpointer test_data) -{ - const char *client = test_data; - GHashTable *options; - NMIP4Config *ip4_config; - const NMPlatformIP4Address *address; - - /* Ensure that the missing-subnet-mask handler doesn't mangle classless - * subnet masks at all. The handler should trigger only if the server - * doesn't send the subnet mask. - */ - - options = fill_table (generic_options, NULL); - g_hash_table_insert (options, "new_ip_address", string_to_byte_array_gvalue ("172.16.54.22")); - g_hash_table_insert (options, "new_subnet_mask", string_to_byte_array_gvalue ("255.255.252.0")); - - ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind"); - ASSERT (ip4_config != NULL, - "dhcp-ip4-prefix-classless", "failed to parse DHCP4 options"); - - ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1, - "dhcp-ip4-prefix-classless", "unexpected number of IP4 addresses (not 1)"); - - address = nm_ip4_config_get_address (ip4_config, 0); - ASSERT (address, - "dhcp-ip4-prefix-classless", "missing IP4 address #1"); - - ASSERT (address->plen == 22, - "dhcp-ip4-prefix-classless", "unexpected IP4 address prefix %d (expected 22)", - address->plen); - - g_hash_table_destroy (options); -} - -NMTST_DEFINE (); - -int main (int argc, char **argv) -{ - char *path; - const char *clients[2][2] = { {DHCLIENT_PATH, "dhclient"}, {DHCPCD_PATH, "dhcpcd"} }; - guint32 i; - - nmtst_init_assert_logging (&argc, &argv); - nm_logging_setup ("WARN", "DEFAULT", NULL, NULL); - - for (i = 0; i < 2; i++) { - const char *client_path = clients[i][0]; - const char *client = clients[i][1]; - - if (!client_path || !strlen (client_path)) - continue; - - path = g_strdup_printf ("/dhcp/%s/generic-options", client); - g_test_add_data_func (path, client, test_generic_options); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/wins-options", client); - g_test_add_data_func (path, client, test_wins_options); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/classless-static-routes-1", client); - g_test_add_data_func (path, client, test_classless_static_routes_1); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/classless-static-routes-2", client); - g_test_add_data_func (path, client, test_classless_static_routes_2); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/fedora-dhclient-classless-static-routes", client); - g_test_add_data_func (path, client, test_fedora_dhclient_classless_static_routes); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhclient-invalid-classless-routes-1", client); - g_test_add_data_func (path, client, test_dhclient_invalid_classless_routes_1); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhcpcd-invalid-classless-routes-1", client); - g_test_add_data_func (path, client, test_dhcpcd_invalid_classless_routes_1); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhclient-invalid-classless-routes-2", client); - g_test_add_data_func (path, client, test_dhclient_invalid_classless_routes_2); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhcpcd-invalid-classless-routes-2", client); - g_test_add_data_func (path, client, test_dhcpcd_invalid_classless_routes_2); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhclient-invalid-classless-routes-3", client); - g_test_add_data_func (path, client, test_dhclient_invalid_classless_routes_3); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhcpcd-invalid-classless-routes-3", client); - g_test_add_data_func (path, client, test_dhcpcd_invalid_classless_routes_3); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhclient-gw-in-classless-routes", client); - g_test_add_data_func (path, client, test_dhclient_gw_in_classless_routes); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/dhcpcd-gw-in-classless-routes", client); - g_test_add_data_func (path, client, test_dhcpcd_gw_in_classless_routes); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/escaped-domain-searches", client); - g_test_add_data_func (path, client, test_escaped_domain_searches); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/invalid-escaped-domain-searches", client); - g_test_add_data_func (path, client, test_invalid_escaped_domain_searches); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/ip4-missing-prefix-24", client); - g_test_add_data_func (path, client, test_ip4_missing_prefix_24); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/ip4-missing-prefix-16", client); - g_test_add_data_func (path, client, test_ip4_missing_prefix_16); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/ip4-missing-prefix-8", client); - g_test_add_data_func (path, client, test_ip4_missing_prefix_8); - g_free (path); - - path = g_strdup_printf ("/dhcp/%s/ip4-prefix-classless", client); - g_test_add_data_func (path, client, test_ip4_prefix_classless); - g_free (path); - } - - return g_test_run (); -} - diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c new file mode 100644 index 00000000..f5010dae --- /dev/null +++ b/src/tests/test-general-with-expect.c @@ -0,0 +1,349 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2014 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "NetworkManagerUtils.h" +#include "nm-logging.h" + +#include "nm-test-utils.h" + +/*******************************************/ + +struct test_nm_utils_kill_child_async_data +{ + GMainLoop *loop; + pid_t pid; + gboolean called; + gboolean expected_success; + const int *expected_child_status; +}; + +static void +test_nm_utils_kill_child_async_cb (pid_t pid, gboolean success, int child_status, void *user_data) +{ + struct test_nm_utils_kill_child_async_data *data = user_data; + + g_assert (success == !!data->expected_success); + g_assert (pid == data->pid); + if (data->expected_child_status) + g_assert_cmpint (*data->expected_child_status, ==, child_status); + if (!success) + g_assert_cmpint (child_status, ==, -1); + + data->called = TRUE; + + g_assert (data->loop); + g_main_loop_quit (data->loop); +} + +static gboolean +test_nm_utils_kill_child_async_fail_cb (void *user_data) +{ + g_assert_not_reached (); +} + +static void +test_nm_utils_kill_child_async_do (const char *name, pid_t pid, int sig, guint32 wait_before_kill_msec, gboolean expected_success, const int *expected_child_status) +{ + gboolean success; + struct test_nm_utils_kill_child_async_data data = { }; + int timeout_id; + + data.pid = pid; + data.expected_success = expected_success; + data.expected_child_status = expected_child_status; + + nm_utils_kill_child_async (pid, sig, LOGD_CORE, name, wait_before_kill_msec, test_nm_utils_kill_child_async_cb, &data); + g_assert (!data.called); + + timeout_id = g_timeout_add_seconds (5, test_nm_utils_kill_child_async_fail_cb, &data); + + data.loop = g_main_loop_new (NULL, FALSE); + g_main_run (data.loop); + + g_assert (data.called); + success = g_source_remove (timeout_id); + g_assert (success); + + g_main_destroy (data.loop); +} + +static void +test_nm_utils_kill_child_sync_do (const char *name, pid_t pid, int sig, guint32 wait_before_kill_msec, gboolean expected_success, const int *expected_child_status) +{ + gboolean success; + int child_status = -1; + + success = nm_utils_kill_child_sync (pid, sig, LOGD_CORE, name, &child_status, wait_before_kill_msec, 0); + g_assert (success == !!expected_success); + if (expected_child_status) + g_assert_cmpint (*expected_child_status, ==, child_status); + + g_test_assert_expected_messages (); +} + +static pid_t +test_nm_utils_kill_child_spawn (char **argv, gboolean do_not_reap_child) +{ + GError *error = NULL; + int success; + GPid child_pid; + + success = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | (do_not_reap_child ? G_SPAWN_DO_NOT_REAP_CHILD : 0), + NULL, + NULL, + &child_pid, + &error); + g_assert (success && !error); + return child_pid; +} + +static pid_t +test_nm_utils_kill_child_create_and_join_pgroup (void) +{ + int err, tmp = 0; + int pipefd[2]; + pid_t pgid; + + err = pipe (pipefd); + g_assert (err == 0); + + pgid = fork(); + if (pgid < 0) { + g_assert_not_reached (); + return pgid; + } + + if (pgid == 0) { + /* child process... */ + close (pipefd[0]); + + err = setpgid (0, 0); + g_assert (err == 0); + + err = write (pipefd[1], &tmp, sizeof (tmp)); + g_assert (err == sizeof (tmp)); + + close (pipefd[1]); + exit (0); + } + + close (pipefd[1]); + + err = read (pipefd[0], &tmp, sizeof (tmp)); + g_assert (err == sizeof (tmp)); + + close (pipefd[0]); + + err = setpgid (0, pgid); + g_assert (err == 0); + + + do { + err = waitpid (pgid, &tmp, 0); + } while (err == -1 && errno == EINTR); + g_assert (err == pgid); + g_assert (WIFEXITED (tmp) && WEXITSTATUS(tmp) == 0); + + return pgid; +} + +#define TEST_TOKEN "nm_test_kill_child_process" + +static void +test_nm_utils_kill_child (void) +{ + int err; + GLogLevelFlags fatal_mask; + char *argv_watchdog[] = { + "sh", + "-c", + "sleep 4; " + "kill -KILL 0; #watchdog for #" TEST_TOKEN, + NULL, + }; + char *argv1[] = { + "sh", + "-c", + "trap \"sleep 0.3; exit 10\" EXIT; " + "sleep 100000; exit $? #" TEST_TOKEN, + NULL, + }; + char *argv2[] = { + "sh", + "-c", + "exit 47; #" TEST_TOKEN, + NULL, + }; + char *argv3[] = { + "sh", + "-c", + "trap \"exit 47\" TERM; while true; do :; done; #" TEST_TOKEN, + NULL, + }; + char *argv4[] = { + "sh", + "-c", + "trap \"while true; do :; done\" TERM; while true; do :; done; #" TEST_TOKEN, + NULL, + }; + pid_t gpid; + pid_t pid1a_1, pid1a_2, pid1a_3, pid2a, pid3a, pid4a; + pid_t pid1s_1, pid1s_2, pid1s_3, pid2s, pid3s, pid4s; + + const int expected_exit_47 = 12032; /* exit with status 47 */ + const int expected_signal_TERM = SIGTERM; + const int expected_signal_KILL = SIGKILL; + + gpid = test_nm_utils_kill_child_create_and_join_pgroup (); + + test_nm_utils_kill_child_spawn (argv_watchdog, FALSE); + + pid1s_1 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid1s_2 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid1s_3 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid2s = test_nm_utils_kill_child_spawn (argv2, TRUE); + pid3s = test_nm_utils_kill_child_spawn (argv3, TRUE); + pid4s = test_nm_utils_kill_child_spawn (argv4, TRUE); + + pid1a_1 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid1a_2 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid1a_3 = test_nm_utils_kill_child_spawn (argv1, TRUE); + pid2a = test_nm_utils_kill_child_spawn (argv2, TRUE); + pid3a = test_nm_utils_kill_child_spawn (argv3, TRUE); + pid4a = test_nm_utils_kill_child_spawn (argv4, TRUE); + + /* give processes time to start (and potentially block signals) ... */ + g_usleep (G_USEC_PER_SEC / 10); + + + fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-1' (*): waiting up to 500 milliseconds for process to terminate normally after sending SIGTERM (15)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-1' (*): after sending SIGTERM (15), process * exited by signal 15 (* usec elapsed)"); + test_nm_utils_kill_child_sync_do ("test-s-1-1", pid1s_1, SIGTERM, 1000 / 2, TRUE, &expected_signal_TERM); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-2' (*): waiting for process to terminate after sending SIGKILL (9)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-2' (*): after sending SIGKILL (9), process * exited by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_sync_do ("test-s-1-2", pid1s_2, SIGKILL, 1000 / 2, TRUE, &expected_signal_KILL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): waiting up to 1 milliseconds for process to terminate normally after sending no signal (0)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): sending SIGKILL..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-1-3' (*): after sending no signal (0) and SIGKILL, process * exited by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_sync_do ("test-s-1-3", pid1s_3, 0, 1, TRUE, &expected_signal_KILL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-2' (*): process * already terminated normally with status 47"); + test_nm_utils_kill_child_sync_do ("test-s-2", pid2s, SIGTERM, 1000 / 2, TRUE, &expected_exit_47); + + /* send invalid signal. */ + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*kill child process 'test-s-3-0' (*): failed to send Unexpected signal: Invalid argument (22)"); + test_nm_utils_kill_child_sync_do ("test-s-3-0", pid3s, -1, 0, FALSE, NULL); + + /* really kill pid3s */ + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-3-1' (*): waiting up to 500 milliseconds for process to terminate normally after sending SIGTERM (15)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-3-1' (*): after sending SIGTERM (15), process * exited normally with status 47 (* usec elapsed)"); + test_nm_utils_kill_child_sync_do ("test-s-3-1", pid3s, SIGTERM, 1000 / 2, TRUE, &expected_exit_47); + + /* pid3s should not be a valid process, hence the call should fail. Note, that there + * is a race here. */ + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*kill child process 'test-s-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)"); + test_nm_utils_kill_child_sync_do ("test-s-3-2", pid3s, 0, 0, FALSE, NULL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): waiting up to 1 milliseconds for process to terminate normally after sending SIGTERM (15)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): sending SIGKILL..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-s-4' (*): after sending SIGTERM (15) and SIGKILL, process * exited by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_sync_do ("test-s-4", pid4s, SIGTERM, 1, TRUE, &expected_signal_KILL); + + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 500 milliseconds)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-1' (*): terminated by signal 15 (* usec elapsed)"); + test_nm_utils_kill_child_async_do ("test-a-1-1", pid1a_1, SIGTERM, 1000 / 2, TRUE, &expected_signal_TERM); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-2' (*): wait for process to terminate after sending SIGKILL (9)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-2' (*): terminated by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_async_do ("test-a-1-2", pid1a_2, SIGKILL, 1000 / 2, TRUE, &expected_signal_KILL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): wait for process to terminate after sending no signal (0) (send SIGKILL in 1 milliseconds)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): process not terminated after * usec. Sending SIGKILL signal"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-1-3' (*): terminated by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_async_do ("test-a-1-3", pid1a_3, 0, 1, TRUE, &expected_signal_KILL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-2' (*): process * already terminated normally with status 47"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-2' (*): invoke callback: terminated normally with status 47"); + test_nm_utils_kill_child_async_do ("test-a-2", pid2a, SIGTERM, 1000 / 2, TRUE, &expected_exit_47); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*kill child process 'test-a-3-0' (*): unexpected error sending Unexpected signal: Invalid argument (22)"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-0' (*): invoke callback: killing child failed"); + /* coverity[negative_returns] */ + test_nm_utils_kill_child_async_do ("test-a-3-0", pid3a, -1, 1000 / 2, FALSE, NULL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-1' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 500 milliseconds)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-1' (*): terminated normally with status 47 (* usec elapsed)"); + test_nm_utils_kill_child_async_do ("test-a-3-1", pid3a, SIGTERM, 1000 / 2, TRUE, &expected_exit_47); + + /* pid3a should not be a valid process, hence the call should fail. Note, that there + * is a race here. */ + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, "*kill child process 'test-a-3-2' (*): failed due to unexpected return value -1 by waitpid (No child processes, 10) after sending no signal (0)"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-3-2' (*): invoke callback: killing child failed"); + test_nm_utils_kill_child_async_do ("test-a-3-2", pid3a, 0, 0, FALSE, NULL); + + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): wait for process to terminate after sending SIGTERM (15) (send SIGKILL in 1 milliseconds)..."); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): process not terminated after * usec. Sending SIGKILL signal"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_DEBUG, "*kill child process 'test-a-4' (*): terminated by signal 9 (* usec elapsed)"); + test_nm_utils_kill_child_async_do ("test-a-4", pid4a, SIGTERM, 1, TRUE, &expected_signal_KILL); + + err = setpgid (0, 0); + g_assert (err == 0); + + kill (-gpid, SIGKILL); + + g_log_set_always_fatal (fatal_mask); + + g_test_assert_expected_messages (); +} + + +/*******************************************/ + +NMTST_DEFINE (); + +int +main (int argc, char **argv) +{ + nmtst_init_assert_logging (&argc, &argv); + + nm_logging_setup ("DEBUG", "DEFAULT", NULL, NULL); + + g_test_add_func ("/general/nm_utils_kill_child", test_nm_utils_kill_child); + + return g_test_run (); +} + diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 11c03f0d..f118156b 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -18,14 +18,17 @@ * */ +#include "config.h" + #include #include #include -#include #include "NetworkManagerUtils.h" -#include "nm-utils.h" +#include "nm-logging.h" +#include "nm-core-internal.h" +#include "nm-test-utils.h" static void test_nm_utils_ascii_str_to_int64_check (const char *str, guint base, gint64 min, @@ -66,7 +69,7 @@ test_nm_utils_ascii_str_to_int64_do (const char *str, guint base, gint64 min, NULL, }; const char **ws_pre, **ws_post, **null; - int i; + guint i; if (str == NULL || exp_errno != 0) { test_nm_utils_ascii_str_to_int64_check (str, base, min, max, fallback, exp_errno, exp_val); @@ -179,51 +182,104 @@ ip6_address_clear_host_address_reference (struct in6_addr *dst, struct in6_addr } static void -_randomize_in6_addr (struct in6_addr *addr, GRand *rand) +_randomize_in6_addr (struct in6_addr *addr, GRand *r) { int i; for (i=0; i < 4; i++) - ((guint32 *)addr)[i] = g_rand_int (rand); + ((guint32 *)addr)[i] = g_rand_int (r); } static void test_nm_utils_ip6_address_clear_host_address (void) { - GRand *rand = g_rand_new (); + GRand *r = g_rand_new (); int plen, i; - g_rand_set_seed (rand, 0); + g_rand_set_seed (r, 0); for (plen = 0; plen <= 128; plen++) { for (i =0; i<50; i++) { struct in6_addr addr_src, addr_ref; struct in6_addr addr1, addr2; - _randomize_in6_addr (&addr_src, rand); - _randomize_in6_addr (&addr_ref, rand); - _randomize_in6_addr (&addr1, rand); - _randomize_in6_addr (&addr2, rand); + _randomize_in6_addr (&addr_src, r); + _randomize_in6_addr (&addr_ref, r); + _randomize_in6_addr (&addr1, r); + _randomize_in6_addr (&addr2, r); addr1 = addr_src; ip6_address_clear_host_address_reference (&addr_ref, &addr1, plen); - _randomize_in6_addr (&addr1, rand); - _randomize_in6_addr (&addr2, rand); + _randomize_in6_addr (&addr1, r); + _randomize_in6_addr (&addr2, r); addr1 = addr_src; nm_utils_ip6_address_clear_host_address (&addr2, &addr1, plen); g_assert_cmpint (memcmp (&addr1, &addr_src, sizeof (struct in6_addr)), ==, 0); g_assert_cmpint (memcmp (&addr2, &addr_ref, sizeof (struct in6_addr)), ==, 0); /* test for self assignment/inplace update. */ - _randomize_in6_addr (&addr1, rand); + _randomize_in6_addr (&addr1, r); addr1 = addr_src; nm_utils_ip6_address_clear_host_address (&addr1, &addr1, plen); g_assert_cmpint (memcmp (&addr1, &addr_ref, sizeof (struct in6_addr)), ==, 0); } } - g_rand_free (rand); + g_rand_free (r); +} + + +static void +test_nm_utils_log_connection_diff (void) +{ + NMConnection *connection; + NMConnection *connection2; + + /* if logging is disabled (the default), nm_utils_log_connection_diff() returns + * early without doing anything. Hence, in the normal testing, this test does nothing. + * It only gets interesting, when run verbosely with NMTST_DEBUG=debug ... */ + + nm_log (LOGL_DEBUG, LOGD_CORE, "START TEST test_nm_utils_log_connection_diff..."); + + connection = nm_simple_connection_new (); + nm_connection_add_setting (connection, nm_setting_connection_new ()); + nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test1", ">>> "); + + nm_connection_add_setting (connection, nm_setting_wired_new ()); + nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test2", ">>> "); + + connection2 = nm_simple_connection_new_clone (connection); + nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test3", ">>> "); + + g_object_set (nm_connection_get_setting_connection (connection), + NM_SETTING_CONNECTION_ID, "id", + NM_SETTING_CONNECTION_UUID, "uuid", + NULL); + g_object_set (nm_connection_get_setting_connection (connection2), + NM_SETTING_CONNECTION_ID, "id2", + NM_SETTING_CONNECTION_MASTER, "master2", + NULL); + nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test4", ">>> "); + + nm_connection_add_setting (connection, nm_setting_802_1x_new ()); + nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test5", ">>> "); + + g_object_set (nm_connection_get_setting_802_1x (connection), + NM_SETTING_802_1X_PASSWORD, "id2", + NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED, + NULL); + nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test6", ">>> "); + nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test7", ">>> "); + nm_utils_log_connection_diff (connection2, connection, LOGL_DEBUG, LOGD_CORE, "test8", ">>> "); + + g_clear_object (&connection); + g_clear_object (&connection2); + + connection = nmtst_create_minimal_connection ("id-vpn-1", NULL, NM_SETTING_VPN_SETTING_NAME, NULL); + nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test-vpn-1", ">>> "); + + g_clear_object (&connection); } /*******************************************/ @@ -234,11 +290,10 @@ _match_connection_new (void) NMConnection *connection; NMSettingConnection *s_con; NMSettingWired *s_wired; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip4, *s_ip6; char *uuid; - connection = nm_connection_new (); + connection = nm_simple_connection_new (); s_con = (NMSettingConnection *) nm_setting_connection_new (); nm_connection_add_setting (connection, (NMSetting *) s_con); @@ -254,16 +309,16 @@ _match_connection_new (void) s_wired = (NMSettingWired *) nm_setting_wired_new (); nm_connection_add_setting (connection, (NMSetting *) s_wired); - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); nm_connection_add_setting (connection, (NMSetting *) s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); nm_connection_add_setting (connection, (NMSetting *) s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); return connection; @@ -274,10 +329,10 @@ test_connection_match_basic (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); @@ -287,7 +342,7 @@ test_connection_match_basic (void) s_ip4 = nm_connection_get_setting_ip4_config (orig); g_assert (s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NULL); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); g_assert (matched == NULL); @@ -302,10 +357,10 @@ test_connection_match_ip6_method (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if the generated connection is IPv6 method=link-local, and the @@ -315,14 +370,14 @@ test_connection_match_ip6_method (void) s_ip6 = nm_connection_get_setting_ip6_config (orig); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NULL); s_ip6 = nm_connection_get_setting_ip6_config (copy); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); @@ -338,10 +393,10 @@ test_connection_match_ip6_method_ignore (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if the generated connection is IPv6 method=link-local, and the @@ -350,13 +405,13 @@ test_connection_match_ip6_method_ignore (void) s_ip6 = nm_connection_get_setting_ip6_config (orig); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NULL); s_ip6 = nm_connection_get_setting_ip6_config (copy); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); @@ -372,10 +427,10 @@ test_connection_match_ip6_method_ignore_auto (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP6Config *s_ip6; + NMSettingIPConfig *s_ip6; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if the generated connection is IPv6 method=auto, and the @@ -384,13 +439,13 @@ test_connection_match_ip6_method_ignore_auto (void) s_ip6 = nm_connection_get_setting_ip6_config (orig); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); s_ip6 = nm_connection_get_setting_ip6_config (copy); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); @@ -407,10 +462,10 @@ test_connection_match_ip4_method (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if the generated connection is IPv4 method=disabled, and the @@ -420,14 +475,14 @@ test_connection_match_ip4_method (void) s_ip4 = nm_connection_get_setting_ip4_config (orig); g_assert (s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); s_ip4 = nm_connection_get_setting_ip4_config (copy); g_assert (s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); matched = nm_utils_match_connection (connections, orig, FALSE, NULL, NULL); @@ -450,7 +505,7 @@ test_connection_match_interface_name (void) NMSettingConnection *s_con; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if the generated connection has an interface name and the @@ -482,18 +537,13 @@ test_connection_match_wired (void) NMConnection *orig, *copy, *matched; GSList *connections = NULL; NMSettingWired *s_wired; - GPtrArray *subchan_arr = g_ptr_array_sized_new (3); - GByteArray *mac; - - g_ptr_array_add (subchan_arr, "0.0.8000"); - g_ptr_array_add (subchan_arr, "0.0.8001"); - g_ptr_array_add (subchan_arr, "0.0.8002"); + char *subchan_arr[] = { "0.0.8000", "0.0.8001", "0.0.8002", NULL }; + const char *mac = "52:54:00:ab:db:23"; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); - mac = nm_utils_hwaddr_atoba ("52:54:00:ab:db:23", ARPHRD_ETHER); s_wired = nm_connection_get_setting_wired (orig); g_assert (s_wired); g_object_set (G_OBJECT (s_wired), @@ -502,7 +552,6 @@ test_connection_match_wired (void) NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr, NM_SETTING_WIRED_S390_NETTYPE, "qeth", NULL); - g_byte_array_free (mac, TRUE); s_wired = nm_connection_get_setting_wired (copy); g_assert (s_wired); @@ -515,7 +564,6 @@ test_connection_match_wired (void) g_assert (matched == copy); g_slist_free (connections); - g_ptr_array_free (subchan_arr, TRUE); g_object_unref (orig); g_object_unref (copy); } @@ -525,13 +573,12 @@ test_connection_no_match_ip4_addr (void) { NMConnection *orig, *copy, *matched; GSList *connections = NULL; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - NMIP4Address *nm_addr; - guint32 addr, gw; + NMSettingIPConfig *s_ip4, *s_ip6; + NMIPAddress *nm_addr; + GError *error = NULL; orig = _match_connection_new (); - copy = nm_connection_duplicate (orig); + copy = nm_simple_connection_new_clone (orig); connections = g_slist_append (connections, copy); /* Check that if we have two differences, ipv6.method (exception we allow) and @@ -540,43 +587,37 @@ test_connection_no_match_ip4_addr (void) s_ip6 = nm_connection_get_setting_ip6_config (orig); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NULL); s_ip6 = nm_connection_get_setting_ip6_config (copy); g_assert (s_ip6); g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); s_ip4 = nm_connection_get_setting_ip4_config (orig); g_assert (s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254", NULL); - nm_addr = nm_ip4_address_new (); - inet_pton (AF_INET, "1.1.1.4", &addr); - inet_pton (AF_INET, "1.1.1.254", &gw); - nm_ip4_address_set_address (nm_addr, addr); - nm_ip4_address_set_prefix (nm_addr, 24); - nm_ip4_address_set_gateway (nm_addr, gw); - nm_setting_ip4_config_add_address (s_ip4, nm_addr); - nm_ip4_address_unref (nm_addr); + nm_addr = nm_ip_address_new (AF_INET, "1.1.1.4", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, nm_addr); + nm_ip_address_unref (nm_addr); s_ip4 = nm_connection_get_setting_ip4_config (copy); g_assert (s_ip4); g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP_CONFIG_GATEWAY, "2.2.2.254", NULL); - nm_addr = nm_ip4_address_new (); - inet_pton (AF_INET, "2.2.2.4", &addr); - inet_pton (AF_INET, "2.2.2.254", &gw); - nm_ip4_address_set_address (nm_addr, addr); - nm_ip4_address_set_prefix (nm_addr, 24); - nm_ip4_address_set_gateway (nm_addr, gw); - nm_setting_ip4_config_add_address (s_ip4, nm_addr); - nm_ip4_address_unref (nm_addr); + nm_addr = nm_ip_address_new (AF_INET, "2.2.2.4", 24, &error); + g_assert_no_error (error); + nm_setting_ip_config_add_address (s_ip4, nm_addr); + nm_ip_address_unref (nm_addr); matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); g_assert (matched != copy); @@ -586,19 +627,163 @@ test_connection_no_match_ip4_addr (void) g_object_unref (copy); } +static NMConnection * +_create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority) +{ + NMConnection *c; + NMSettingConnection *s_con; + + c = nmtst_create_minimal_connection (id, NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, autoconnect, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, autoconnect_priority, + NULL); + nmtst_connection_normalize (c); + return c; +} + +static void +_test_connection_sort_autoconnect_priority_one (NMConnection **list, gboolean shuffle) +{ + int i, j; + int count = 0; + gs_unref_ptrarray GPtrArray *connections = g_ptr_array_new (); + + while (list[count]) + count++; + g_assert (count > 1); + + /* copy the list of connections over to @connections and shuffle. */ + for (i = 0; i < count; i++) + g_ptr_array_add (connections, list[i]); + if (shuffle) { + for (i = count - 1; i > 0; i--) { + j = g_rand_int (nmtst_get_rand ()) % (i + 1); + NMTST_SWAP (connections->pdata[i], connections->pdata[j]); + } + } + + /* sort it... */ + g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority); + + for (i = 0; i < count; i++) { + if (list[i] == connections->pdata[i]) + continue; + if (shuffle && nm_utils_cmp_connection_by_autoconnect_priority (&list[i], (NMConnection **) &connections->pdata[i]) == 0) + continue; + g_message ("After sorting, the order of connections is not as expected!! Offending index: %d", i); + for (j = 0; j < count; j++) + g_message (" %3d: %p/%-20s - %p/%-20s", j, list[j], nm_connection_get_id (list[j]), connections->pdata[j], nm_connection_get_id (connections->pdata[j])); + g_assert_not_reached (); + } +} + +static void +_test_connection_sort_autoconnect_priority_free (NMConnection **list) +{ + while (*list) { + g_object_unref (*list); + *list = NULL; + } +} + +static void +test_connection_sort_autoconnect_priority (void) +{ + NMConnection *c1[] = { + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/99", TRUE, 99), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/-1", TRUE, -1), + _create_connection_autoconnect ("AC/-3", TRUE, -3), + _create_connection_autoconnect ("ac/0", FALSE, 0), + _create_connection_autoconnect ("ac/0", FALSE, 0), + _create_connection_autoconnect ("ac/1", FALSE, 1), + _create_connection_autoconnect ("ac/-1", FALSE, -1), + _create_connection_autoconnect ("ac/1", FALSE, 1), + _create_connection_autoconnect ("ac/0", FALSE, 0), + NULL, + }; + NMConnection *c2[] = { + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/99", TRUE, 99), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/-1", TRUE, -1), + _create_connection_autoconnect ("AC/-3", TRUE, -3), + _create_connection_autoconnect ("ac/0", FALSE, 0), + NULL, + }; + + _test_connection_sort_autoconnect_priority_one (c1, FALSE); + _test_connection_sort_autoconnect_priority_one (c2, FALSE); + _test_connection_sort_autoconnect_priority_one (c1, TRUE); + _test_connection_sort_autoconnect_priority_one (c2, TRUE); + + _test_connection_sort_autoconnect_priority_free (c1); + _test_connection_sort_autoconnect_priority_free (c2); +} + /*******************************************/ +static void +__test_uuid (const char *expected_uuid, const char *str, gssize slen, char *uuid_test) +{ + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed (1): text=%s, len=%lld, expected=%s, uuid_test=%s", + str, (long long) slen, expected_uuid, uuid_test); + } + g_free (uuid_test); + + uuid_test = nm_utils_uuid_generate_from_string (str, slen, NM_UTILS_UUID_TYPE_VARIANT3, NM_UTILS_UUID_NS); + + g_assert (uuid_test); + g_assert (nm_utils_is_uuid (uuid_test)); + + if (strcmp (uuid_test, expected_uuid)) { + g_error ("UUID test failed (2): text=%s; len=%lld, expected=%s, uuid2=%s", + str, (long long) slen, expected_uuid, uuid_test); + } + g_free (uuid_test); +} + +#define _test_uuid(expected_uuid, str, strlen, ...) __test_uuid (expected_uuid, str, strlen, nm_utils_uuid_generate_from_strings(__VA_ARGS__, NULL)) + +static void +test_nm_utils_uuid_generate_from_strings (void) +{ + _test_uuid ("b07c334a-399b-32de-8d50-58e4e08f98e3", "", 0, NULL); + _test_uuid ("b8a426cb-bcb5-30a3-bd8f-6786fea72df9", "\0", 1, ""); + _test_uuid ("12a4a982-7aae-39e1-951e-41aeb1250959", "a\0", 2, "a"); + _test_uuid ("69e22c7e-f89f-3a43-b239-1cb52ed8db69", "aa\0", 3, "aa"); + _test_uuid ("59829fd3-5ad5-3d90-a7b0-4911747e4088", "\0\0", 2, "", ""); + _test_uuid ("01ad0e06-6c50-3384-8d86-ddab81421425", "a\0\0", 3, "a", ""); + _test_uuid ("e1ed8647-9ed3-3ec8-8c6d-e8204524d71d", "aa\0\0", 4, "aa", ""); + _test_uuid ("fb1c7cd6-275c-3489-9382-83b900da8af0", "\0a\0", 3, "", "a"); + _test_uuid ("5d79494e-c4ba-31a6-80a2-d6016ccd7e17", "a\0a\0", 4, "a", "a"); + _test_uuid ("fd698d86-1b60-3ebe-855f-7aada9950a8d", "aa\0a\0", 5, "aa", "a"); + _test_uuid ("8c573b48-0f01-30ba-bb94-c5f59f4fe517", "\0aa\0", 4, "", "aa"); + _test_uuid ("2bdd3d46-eb83-3c53-a41b-a724d04b5544", "a\0aa\0", 5, "a", "aa"); + _test_uuid ("13d4b780-07c1-3ba7-b449-81c4844ef039", "aa\0aa\0", 6, "aa", "aa"); + _test_uuid ("dd265bf7-c05a-3037-9939-b9629858a477", "a\0b\0", 4, "a", "b"); +} + +/*******************************************/ + +NMTST_DEFINE (); + int main (int argc, char **argv) { - g_test_init (&argc, &argv, NULL); - -#if !GLIB_CHECK_VERSION (2, 35, 0) - g_type_init (); -#endif + nmtst_init_with_logging (&argc, &argv, NULL, "ALL"); g_test_add_func ("/general/nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64); g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address); + g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff); g_test_add_func ("/general/connection-match/basic", test_connection_match_basic); g_test_add_func ("/general/connection-match/ip6-method", test_connection_match_ip6_method); @@ -609,6 +794,10 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr); + g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); + + g_test_add_func ("/general/nm_utils_uuid_generate_from_strings", test_nm_utils_uuid_generate_from_strings); + return g_test_run (); } diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index 3eee5f13..657f7e05 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -18,11 +18,14 @@ * */ +#include "config.h" + #include #include #include #include "nm-ip4-config.h" +#include "nm-platform.h" static void addr_init (NMPlatformIP4Address *a, const char *addr, const char *peer, guint plen) @@ -138,7 +141,7 @@ test_subtract (void) nm_ip4_config_add_wins (dst, expected_wins); nm_ip4_config_set_mss (dst, expected_mss); - nm_ip4_config_set_mtu (dst, expected_mtu); + nm_ip4_config_set_mtu (dst, expected_mtu, NM_IP_CONFIG_SOURCE_UNKNOWN); nm_ip4_config_subtract (dst, src); @@ -193,18 +196,18 @@ test_compare_with_source (void) /* Address */ addr_init (&addr, "1.2.3.4", NULL, 24); - addr.source = NM_PLATFORM_SOURCE_USER; + addr.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); - addr.source = NM_PLATFORM_SOURCE_VPN; + addr.source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (b, &addr); /* Route */ route_new (&route, "10.0.0.0", 8, "192.168.1.1"); - route.source = NM_PLATFORM_SOURCE_USER; + route.source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); - route.source = NM_PLATFORM_SOURCE_VPN; + route.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 */ @@ -225,31 +228,31 @@ test_add_address_with_source (void) /* Test that a higher priority source is not overwritten */ addr_init (&addr, "1.2.3.4", NULL, 24); - addr.source = NM_PLATFORM_SOURCE_USER; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); - addr.source = NM_PLATFORM_SOURCE_VPN; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_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_PLATFORM_SOURCE_KERNEL; + 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_PLATFORM_SOURCE_KERNEL); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - addr.source = NM_PLATFORM_SOURCE_USER; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -265,31 +268,31 @@ test_add_route_with_source (void) /* Test that a higher priority source is not overwritten */ route_new (&route, "1.2.3.4", 24, "1.2.3.1"); - route.source = NM_PLATFORM_SOURCE_USER; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); - route.source = NM_PLATFORM_SOURCE_VPN; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->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_PLATFORM_SOURCE_KERNEL; + route.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_PLATFORM_SOURCE_KERNEL); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - route.source = NM_PLATFORM_SOURCE_USER; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -309,9 +312,9 @@ test_merge_subtract_mss_mtu (void) /* add MSS, MTU to configs to test them */ nm_ip4_config_set_mss (cfg2, expected_mss2); - nm_ip4_config_set_mtu (cfg2, expected_mtu2); + nm_ip4_config_set_mtu (cfg2, expected_mtu2, NM_IP_CONFIG_SOURCE_UNKNOWN); nm_ip4_config_set_mss (cfg3, expected_mss3); - nm_ip4_config_set_mtu (cfg3, expected_mtu3); + nm_ip4_config_set_mtu (cfg3, expected_mtu3, NM_IP_CONFIG_SOURCE_UNKNOWN); nm_ip4_config_merge (cfg1, cfg2); /* ensure MSS and MTU are in cfg1 */ diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 75fe28ee..9e1d5651 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -18,6 +18,8 @@ * */ +#include "config.h" + #include #include #include @@ -25,6 +27,7 @@ #include "nm-ip6-config.h" #include "nm-logging.h" +#include "nm-platform.h" #include "nm-test-utils.h" static NMIP6Config * @@ -131,18 +134,18 @@ test_compare_with_source (void) /* Address */ addr = *nmtst_platform_ip6_address ("1122:3344:5566::7788", NULL, 64); - addr.source = NM_PLATFORM_SOURCE_USER; + addr.source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); - addr.source = NM_PLATFORM_SOURCE_VPN; + 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_PLATFORM_SOURCE_USER; + route.source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_route (a, &route); - route.source = NM_PLATFORM_SOURCE_VPN; + route.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 */ @@ -163,31 +166,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_PLATFORM_SOURCE_USER; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); - addr.source = NM_PLATFORM_SOURCE_VPN; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_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_PLATFORM_SOURCE_KERNEL; + 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_PLATFORM_SOURCE_KERNEL); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - addr.source = NM_PLATFORM_SOURCE_USER; + 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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_addr->source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -203,31 +206,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_PLATFORM_SOURCE_USER; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); - route.source = NM_PLATFORM_SOURCE_VPN; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->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_PLATFORM_SOURCE_KERNEL; + route.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_PLATFORM_SOURCE_KERNEL); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_KERNEL); - route.source = NM_PLATFORM_SOURCE_USER; + route.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_PLATFORM_SOURCE_USER); + g_assert_cmpint (test_route->source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); } @@ -285,33 +288,33 @@ test_nm_ip6_config_addresses_sort (void) #define ADDR_ADD(...) nm_ip6_config_add_address (config, nmtst_platform_ip6_address_full (__VA_ARGS__)) nm_ip6_config_reset_addresses (config); - ADDR_ADD("2607:f0d0:1002:51::4", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_PLATFORM_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); - ADDR_ADD("2607:f0d0:1002:51::3", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("fec0::1", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("::1", NULL, 128, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::2", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_TENTATIVE); + ADDR_ADD("2607:f0d0:1002:51::4", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); + ADDR_ADD("2607:f0d0:1002:51::3", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("fec0::1", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("::1", NULL, 128, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::2", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_TENTATIVE); test_nm_ip6_config_addresses_sort_check (config, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, 8); test_nm_ip6_config_addresses_sort_check (config, NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED, 8); test_nm_ip6_config_addresses_sort_check (config, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR, 8); nm_ip6_config_reset_addresses (config); - ADDR_ADD("2607:f0d0:1002:51::3", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::4", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_PLATFORM_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); - ADDR_ADD("fec0::1", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_PLATFORM_SOURCE_KERNEL, 0, 0, 0, 0); - ADDR_ADD("::1", NULL, 128, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::2", NULL, 64, 0, NM_PLATFORM_SOURCE_USER, 0, 0, 0, IFA_F_TENTATIVE); + ADDR_ADD("2607:f0d0:1002:51::3", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("2607:f0d0:1002:51::4", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); + ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); + ADDR_ADD("fec0::1", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); + ADDR_ADD("::1", NULL, 128, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); + ADDR_ADD("2607:f0d0:1002:51::2", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_TENTATIVE); test_nm_ip6_config_addresses_sort_check (config, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, 8); #undef ADDR_ADD diff --git a/src/tests/test-resolvconf-capture.c b/src/tests/test-resolvconf-capture.c index cde4bbe5..f5cb298b 100644 --- a/src/tests/test-resolvconf-capture.c +++ b/src/tests/test-resolvconf-capture.c @@ -18,10 +18,15 @@ * */ +#include "config.h" + #include #include +#include #include "NetworkManagerUtils.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-platform.h" static void diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c new file mode 100644 index 00000000..a05588b8 --- /dev/null +++ b/src/tests/test-wired-defname.c @@ -0,0 +1,130 @@ +/* -*- 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, 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + * + */ + +#include "config.h" + +#include +#include + +#include +#include +#include "nm-device-ethernet-utils.h" + +static NMConnection * +_new_connection (const char *id) +{ + NMConnection *a; + NMSetting *setting; + + a = nm_simple_connection_new (); + setting = nm_setting_connection_new (); + g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NULL); + nm_connection_add_setting (a, setting); + return a; +} + +/*******************************************/ + +static void +test_defname_no_connections (void) +{ + char *name; + + name = nm_device_ethernet_utils_get_default_wired_name (NULL); + g_assert_cmpstr (name, ==, "Wired connection 1"); +} + +/*******************************************/ + +static void +test_defname_no_conflict (void) +{ + GSList *list = NULL; + char *name; + + list = g_slist_append (list, _new_connection ("asdfasdfasdfadf")); + 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); + g_assert_cmpstr (name, ==, "Wired connection 1"); + + g_slist_free_full (list, g_object_unref); +} + +/*******************************************/ + +static void +test_defname_conflict (void) +{ + GSList *list = NULL; + char *name; + + list = g_slist_append (list, _new_connection ("asdfasdfasdfadf")); + 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); + g_assert_cmpstr (name, ==, "Wired connection 2"); + + g_slist_free_full (list, g_object_unref); +} + +/*******************************************/ + +static void +test_defname_multiple_conflicts (void) +{ + GSList *list = NULL; + char *name; + + list = g_slist_append (list, _new_connection ("random gsm connection")); + list = g_slist_append (list, _new_connection ("home wifi")); + list = g_slist_append (list, _new_connection ("Wired connection 1")); + list = g_slist_append (list, _new_connection ("Wired connection 2")); + list = g_slist_append (list, _new_connection ("Wired connection 3")); + 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); + g_assert_cmpstr (name, ==, "Wired connection 4"); + + g_slist_free_full (list, g_object_unref); +} + +/*******************************************/ + +int +main (int argc, char **argv) +{ +#if !GLIB_CHECK_VERSION (2, 35, 0) + g_type_init (); +#endif + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/defname/no_connections", test_defname_no_connections); + g_test_add_func ("/defname/no_conflict", test_defname_no_conflict); + g_test_add_func ("/defname/conflict", test_defname_conflict); + g_test_add_func ("/defname/multiple_conflicts", test_defname_multiple_conflicts); + + return g_test_run (); +} + diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index d66dcfdb..cb07c7f9 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -19,6 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include #include #include @@ -27,16 +29,12 @@ #include #include -#include "NetworkManager.h" -#include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" -#include "nm-setting-connection.h" -#include "nm-setting-vpn.h" -#include "nm-setting-ip4-config.h" +#include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-dbus-manager.h" #include "nm-platform.h" #include "nm-logging.h" -#include "nm-utils.h" #include "nm-active-connection.h" #include "nm-dbus-glib-types.h" #include "NetworkManagerUtils.h" @@ -44,10 +42,12 @@ #include "settings/nm-settings-connection.h" #include "nm-dispatcher.h" #include "nm-agent-manager.h" +#include "nm-core-internal.h" +#include "nm-default-route-manager.h" #include "nm-vpn-connection-glue.h" -G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) +G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) typedef enum { /* Only system secrets */ @@ -62,7 +62,7 @@ typedef enum { SECRETS_REQ_LAST } SecretsReq; -/* Internal VPN states, private to NMVPNConnection */ +/* Internal VPN states, private to NMVpnConnection */ typedef enum { STATE_UNKNOWN = 0, STATE_WAITING, @@ -79,6 +79,8 @@ typedef enum { typedef struct { NMConnection *connection; + gboolean service_can_persist; + gboolean connection_can_persist; guint32 secrets_id; SecretsReq secrets_idx; @@ -86,7 +88,9 @@ typedef struct { VpnState vpn_state; guint dispatcher_id; - NMVPNConnectionStateReason failure_reason; + NMVpnConnectionStateReason failure_reason; + + NMVpnServiceState service_state; DBusGProxy *proxy; GHashTable *connect_hash; @@ -103,13 +107,14 @@ typedef struct { int ip_ifindex; char *banner; guint32 mtu; -} NMVPNConnectionPrivate; +} NMVpnConnectionPrivate; -#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate)) +#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVpnConnectionPrivate)) enum { VPN_STATE_CHANGED, INTERNAL_STATE_CHANGED, + INTERNAL_RETRY_AFTER_FAILURE, LAST_SIGNAL }; @@ -127,7 +132,7 @@ enum { LAST_PROP }; -static void get_secrets (NMVPNConnection *self, +static void get_secrets (NMVpnConnection *self, SecretsReq secrets_idx, const char **hints); @@ -136,14 +141,14 @@ static void plugin_interactive_secrets_required (DBusGProxy *proxy, const char **secrets, gpointer user_data); -static void _set_vpn_state (NMVPNConnection *connection, +static void _set_vpn_state (NMVpnConnection *connection, VpnState vpn_state, - NMVPNConnectionStateReason reason, + NMVpnConnectionStateReason reason, gboolean quitting); /*********************************************************************/ -static NMVPNConnectionState +static NMVpnConnectionState _state_to_nm_vpn_state (VpnState state) { switch (state) { @@ -173,7 +178,7 @@ _state_to_nm_vpn_state (VpnState state) case STATE_FAILED: return NM_VPN_CONNECTION_STATE_FAILED; default: - return STATE_UNKNOWN; + return NM_VPN_CONNECTION_STATE_UNKNOWN; } } @@ -203,9 +208,9 @@ _state_to_ac_state (VpnState vpn_state) } static void -call_plugin_disconnect (NMVPNConnection *self) +call_plugin_disconnect (NMVpnConnection *self) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *error = NULL; if (priv->proxy) { @@ -222,9 +227,9 @@ call_plugin_disconnect (NMVPNConnection *self) } static void -vpn_cleanup (NMVPNConnection *connection, NMDevice *parent_dev) +vpn_cleanup (NMVpnConnection *connection, NMDevice *parent_dev) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); if (priv->ip_ifindex) { nm_platform_link_set_down (priv->ip_ifindex); @@ -252,8 +257,8 @@ vpn_cleanup (NMVPNConnection *connection, NMDevice *parent_dev) static void dispatcher_pre_down_done (guint call_id, gpointer user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); priv->dispatcher_id = 0; _set_vpn_state (self, STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); @@ -262,17 +267,17 @@ dispatcher_pre_down_done (guint call_id, gpointer user_data) static void dispatcher_pre_up_done (guint call_id, gpointer user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); priv->dispatcher_id = 0; _set_vpn_state (self, STATE_ACTIVATED, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); } static void -dispatcher_cleanup (NMVPNConnection *self) +dispatcher_cleanup (NMVpnConnection *self) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); if (priv->dispatcher_id) { nm_dispatcher_call_cancel (priv->dispatcher_id); @@ -281,14 +286,14 @@ dispatcher_cleanup (NMVPNConnection *self) } static void -_set_vpn_state (NMVPNConnection *connection, +_set_vpn_state (NMVpnConnection *connection, VpnState vpn_state, - NMVPNConnectionStateReason reason, + NMVpnConnectionStateReason reason, gboolean quitting) { - NMVPNConnectionPrivate *priv; + NMVpnConnectionPrivate *priv; VpnState old_vpn_state; - NMVPNConnectionState new_external_state, old_external_state; + NMVpnConnectionState new_external_state, old_external_state; NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection)); g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); @@ -319,6 +324,9 @@ _set_vpn_state (NMVPNConnection *connection, dispatcher_cleanup (connection); + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), connection); + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), connection); + /* The connection gets destroyed by the VPN manager when it enters the * disconnected/failed state, but we need to keep it around for a bit * to send out signals and handle the dispatcher. So ref it. @@ -434,12 +442,34 @@ _set_vpn_state (NMVPNConnection *connection, g_object_unref (parent_dev); } +static gboolean +_service_and_connection_can_persist (NMVpnConnection *self) +{ + return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist && + NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist; +} + +static gboolean +_connection_only_can_persist (NMVpnConnection *self) +{ + return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection_can_persist && + !NM_VPN_CONNECTION_GET_PRIVATE (self)->service_can_persist; +} + static void device_state_changed (NMActiveConnection *active, NMDevice *device, NMDeviceState new_state, NMDeviceState old_state) { + if (_service_and_connection_can_persist (NM_VPN_CONNECTION (active))) { + if (new_state <= NM_DEVICE_STATE_DISCONNECTED || + new_state == NM_DEVICE_STATE_FAILED) { + nm_active_connection_set_device (active, NULL); + } + return; + } + if (new_state <= NM_DEVICE_STATE_DISCONNECTED) { _set_vpn_state (NM_VPN_CONNECTION (active), STATE_DISCONNECTED, @@ -463,6 +493,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32 NMIP4Config *parent_config; guint32 parent_gw; NMPlatformIP4Route route; + guint32 route_metric; g_return_if_fail (NM_IS_IP4_CONFIG (config)); g_return_if_fail (NM_IS_DEVICE (parent_device)); @@ -478,6 +509,8 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32 if (!parent_gw) return; + route_metric = nm_device_get_ip4_route_metric (parent_device); + memset (&route, 0, sizeof (route)); route.network = vpn_gw; route.plen = 32; @@ -490,8 +523,8 @@ 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_PLATFORM_SOURCE_VPN; - route.metric = nm_device_get_priority (parent_device); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; nm_ip4_config_add_route (config, &route); /* Ensure there's a route to the parent device's gateway through the @@ -502,8 +535,8 @@ 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_PLATFORM_SOURCE_VPN; - route.metric = nm_device_get_priority (parent_device); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; nm_ip4_config_add_route (config, &route); } @@ -516,6 +549,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, NMIP6Config *parent_config; const struct in6_addr *parent_gw; NMPlatformIP6Route route; + guint32 route_metric; g_return_if_fail (NM_IS_IP6_CONFIG (config)); g_return_if_fail (NM_IS_DEVICE (parent_device)); @@ -527,6 +561,8 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, if (!parent_gw) return; + route_metric = nm_device_get_ip6_route_metric (parent_device); + memset (&route, 0, sizeof (route)); route.network = *vpn_gw; route.plen = 128; @@ -539,8 +575,8 @@ 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_PLATFORM_SOURCE_VPN; - route.metric = nm_device_get_priority (parent_device); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; nm_ip6_config_add_route (config, &route); /* Ensure there's a route to the parent device's gateway through the @@ -551,13 +587,13 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, memset (&route, 0, sizeof (route)); route.network = *parent_gw; route.plen = 128; - route.source = NM_PLATFORM_SOURCE_VPN; - route.metric = nm_device_get_priority (parent_device); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; nm_ip6_config_add_route (config, &route); } -NMVPNConnection * +NMVpnConnection * nm_vpn_connection_new (NMConnection *connection, NMDevice *parent_device, const char *specific_object, @@ -566,7 +602,7 @@ nm_vpn_connection_new (NMConnection *connection, g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); - return (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, + return (NMVpnConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NM_ACTIVE_CONNECTION_INT_CONNECTION, connection, NM_ACTIVE_CONNECTION_INT_DEVICE, parent_device, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, @@ -576,17 +612,17 @@ nm_vpn_connection_new (NMConnection *connection, } static const char * -nm_vpn_connection_get_service (NMVPNConnection *connection) +nm_vpn_connection_get_service (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - NMSettingVPN *s_vpn; + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMSettingVpn *s_vpn; s_vpn = nm_connection_get_setting_vpn (priv->connection); return nm_setting_vpn_get_service_type (s_vpn); } static const char * -vpn_plugin_failure_to_string (NMVPNPluginFailure failure) +vpn_plugin_failure_to_string (NMVpnPluginFailure failure) { switch (failure) { case NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED: @@ -603,10 +639,10 @@ vpn_plugin_failure_to_string (NMVPNPluginFailure failure) static void plugin_failed (DBusGProxy *proxy, - NMVPNPluginFailure plugin_failure, + NMVpnPluginFailure plugin_failure, gpointer user_data) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (user_data); nm_log_warn (LOGD_VPN, "VPN plugin failed: %s (%d)", vpn_plugin_failure_to_string (plugin_failure), plugin_failure); @@ -620,11 +656,12 @@ plugin_failed (DBusGProxy *proxy, break; default: priv->failure_reason = NM_VPN_CONNECTION_STATE_REASON_UNKNOWN; + break; } } static const char * -vpn_service_state_to_string (NMVPNServiceState state) +vpn_service_state_to_string (NMVpnServiceState state) { switch (state) { case NM_VPN_SERVICE_STATE_INIT: @@ -662,13 +699,13 @@ static const char *state_table[] = { static const char * vpn_state_to_string (VpnState state) { - if (state >= 0 && state < G_N_ELEMENTS (state_table)) + if ((gsize) state < G_N_ELEMENTS (state_table)) return state_table[state]; return "unknown"; } static const char * -vpn_reason_to_string (NMVPNConnectionStateReason reason) +vpn_reason_to_string (NMVpnConnectionStateReason reason) { switch (reason) { case NM_VPN_CONNECTION_STATE_REASON_NONE: @@ -701,36 +738,52 @@ vpn_reason_to_string (NMVPNConnectionStateReason reason) static void plugin_state_changed (DBusGProxy *proxy, - NMVPNServiceState state, + NMVpnServiceState new_service_state, gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnServiceState old_service_state = priv->service_state; nm_log_info (LOGD_VPN, "VPN plugin state changed: %s (%d)", - vpn_service_state_to_string (state), state); + vpn_service_state_to_string (new_service_state), new_service_state); + priv->service_state = new_service_state; - if (state == NM_VPN_SERVICE_STATE_STOPPED) { + if (new_service_state == NM_VPN_SERVICE_STATE_STOPPED) { /* Clear connection secrets to ensure secrets get requested each time the * connection is activated. */ nm_connection_clear_secrets (priv->connection); if ((priv->vpn_state >= STATE_WAITING) && (priv->vpn_state <= STATE_ACTIVATED)) { + VpnState old_state = priv->vpn_state; + nm_log_info (LOGD_VPN, "VPN plugin state change reason: %s (%d)", vpn_reason_to_string (priv->failure_reason), priv->failure_reason); _set_vpn_state (connection, STATE_FAILED, priv->failure_reason, FALSE); /* Reset the failure reason */ priv->failure_reason = NM_VPN_CONNECTION_STATE_REASON_UNKNOWN; + + /* If the connection failed, the service cannot persist, but the + * connection can persist, ask listeners to re-activate the connection. + */ + if ( old_state == STATE_ACTIVATED + && priv->vpn_state == STATE_FAILED + && _connection_only_can_persist (connection)) + g_signal_emit (connection, signals[INTERNAL_RETRY_AFTER_FAILURE], 0); } + } else if (new_service_state == NM_VPN_SERVICE_STATE_STARTING && + old_service_state == NM_VPN_SERVICE_STATE_STARTED) { + /* The VPN service got disconnected and is attempting to reconnect */ + _set_vpn_state (connection, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_CONNECT_TIMEOUT, FALSE); } } static void -print_vpn_config (NMVPNConnection *connection) +print_vpn_config (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); const NMPlatformIP4Address *address4; const NMPlatformIP6Address *address6; char *dns_domain = NULL; @@ -831,41 +884,29 @@ print_vpn_config (NMVPNConnection *connection) } } -static gboolean -nm_vpn_connection_apply_config (NMVPNConnection *connection) +static void +apply_parent_device_config (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection)); NMIP4Config *vpn4_parent_config = NULL; NMIP6Config *vpn6_parent_config = NULL; - if (priv->ip_ifindex > 0) { - nm_platform_link_set_up (priv->ip_ifindex); + if (priv->ip4_config) + vpn4_parent_config = nm_ip4_config_new (); + if (priv->ip6_config) + vpn6_parent_config = nm_ip6_config_new (); - if (priv->ip4_config) { - if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex)) - return FALSE; - } - - if (priv->ip6_config) { - if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex)) - return FALSE; - } - - if (priv->ip4_config) - vpn4_parent_config = nm_ip4_config_new (); - if (priv->ip6_config) - vpn6_parent_config = nm_ip6_config_new (); - } else { + if (priv->ip_ifindex <= 0) { /* If the VPN didn't return a network interface, it is a route-based * VPN (like kernel IPSec) and all IP addressing and routing should * be done on the parent interface instead. */ - if (priv->ip4_config) - vpn4_parent_config = g_object_ref (priv->ip4_config); - if (priv->ip6_config) - vpn6_parent_config = g_object_ref (priv->ip6_config); + if (vpn4_parent_config) + nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config); + if (vpn6_parent_config) + nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config); } if (vpn4_parent_config) { @@ -884,6 +925,32 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection) nm_device_set_vpn6_config (parent_dev, vpn6_parent_config); g_object_unref (vpn6_parent_config); } +} + +static gboolean +nm_vpn_connection_apply_config (NMVpnConnection *connection) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + if (priv->ip_ifindex > 0) { + nm_platform_link_set_up (priv->ip_ifindex); + + if (priv->ip4_config) { + if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex, + nm_vpn_connection_get_ip4_route_metric (connection))) + return FALSE; + } + + if (priv->ip6_config) { + if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex)) + return FALSE; + } + } + + apply_parent_device_config (connection); + + nm_default_route_manager_ip4_update_default_route (nm_default_route_manager_get (), connection); + nm_default_route_manager_ip6_update_default_route (nm_default_route_manager_get (), connection); nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) complete.", nm_connection_get_id (priv->connection)); @@ -892,17 +959,13 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection) } static void -nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection, +nm_vpn_connection_config_maybe_complete (NMVpnConnection *connection, gboolean success) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - if (priv->connect_timeout == 0) { - /* config_complete() was already called with an error; - * ignore further calls. - */ + if (priv->vpn_state < STATE_IP_CONFIG_GET || priv->vpn_state > STATE_ACTIVATED) return; - } if (success) { if ( (priv->has_ip4 && !priv->ip4_config) @@ -912,8 +975,10 @@ nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection, } } - g_source_remove (priv->connect_timeout); - priv->connect_timeout = 0; + if (priv->connect_timeout) { + g_source_remove (priv->connect_timeout); + priv->connect_timeout = 0; + } if (success) { print_vpn_config (connection); @@ -935,12 +1000,18 @@ nm_vpn_connection_config_maybe_complete (NMVPNConnection *connection, nm_connection_get_id (priv->connection), property) static gboolean -process_generic_config (NMVPNConnection *connection, +process_generic_config (NMVpnConnection *connection, GHashTable *config_hash) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); GValue *val; + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CAN_PERSIST); + if (val && G_VALUE_HOLDS_BOOLEAN (val) && g_value_get_boolean (val)) { + /* Defaults to FALSE, so only let service indicate TRUE */ + priv->service_can_persist = TRUE; + } + g_clear_pointer (&priv->ip_iface, g_free); val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CONFIG_TUNDEV); if (val) { @@ -1014,8 +1085,8 @@ nm_vpn_connection_config_get (DBusGProxy *proxy, GHashTable *config_hash, gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); GValue *val; nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) reply received.", @@ -1049,18 +1120,34 @@ nm_vpn_connection_config_get (DBusGProxy *proxy, g_clear_object (&priv->ip6_config); } -static guint -vpn_routing_metric (NMVPNConnection *connection) +guint32 +nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - if (priv->ip_ifindex) - return NM_PLATFORM_ROUTE_METRIC_DEFAULT; - else { - NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (connection)); + if (priv->connection) { + gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (priv->connection)); - return nm_device_get_priority (parent_dev); + if (route_metric >= 0) + return route_metric; } + + return NM_VPN_ROUTE_METRIC_DEFAULT; +} + +guint32 +nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *connection) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + + if (priv->connection) { + gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (priv->connection)); + + if (route_metric >= 0) + return route_metric; + } + + return NM_VPN_ROUTE_METRIC_DEFAULT; } static void @@ -1068,12 +1155,13 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, GHashTable *config_hash, gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMPlatformIP4Address address; NMIP4Config *config; GValue *val; int i; + guint32 route_metric; if (priv->vpn_state == STATE_CONNECT) _set_vpn_state (connection, STATE_IP_CONFIG_GET, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); @@ -1126,7 +1214,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, address.plen = g_value_get_uint (val); if (address.address && address.plen) { - address.source = NM_PLATFORM_SOURCE_VPN; + address.source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (config, &address); } else { nm_log_err (LOGD_VPN, "invalid IP4 config received!"); @@ -1156,7 +1244,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, nm_ip4_config_set_mss (config, g_value_get_uint (val)); if (priv->mtu) - nm_ip4_config_set_mtu (config, priv->mtu); + nm_ip4_config_set_mtu (config, priv->mtu, NM_IP_CONFIG_SOURCE_VPN); val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN); if (val) @@ -1171,6 +1259,8 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, nm_ip4_config_add_domain (config, *domain); } + route_metric = nm_vpn_connection_get_ip4_route_metric (connection); + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES); if (val) { GSList *routes; @@ -1178,15 +1268,15 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, routes = nm_utils_ip4_routes_from_gvalue (val); for (iter = routes; iter; iter = iter->next) { - NMIP4Route *item = iter->data; + NMIPRoute *item = iter->data; NMPlatformIP4Route route; memset (&route, 0, sizeof (route)); - route.network = nm_ip4_route_get_dest (item); - route.plen = nm_ip4_route_get_prefix (item); - route.gateway = nm_ip4_route_get_next_hop (item); - route.source = NM_PLATFORM_SOURCE_VPN; - route.metric = vpn_routing_metric (connection); + nm_ip_route_get_dest_binary (item, &route.network); + route.plen = nm_ip_route_get_prefix (item); + nm_ip_route_get_next_hop_binary (item, &route.gateway); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; /* Ignore host routes to the VPN gateway since NM adds one itself * below. Since NM knows more about the routing situation than @@ -1200,7 +1290,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, nm_ip4_config_add_route (config, &route); } - g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref); + g_slist_free_full (routes, (GDestroyNotify) nm_ip_route_unref); } val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT); @@ -1210,8 +1300,9 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, /* Merge in user overrides from the NMConnection's IPv4 setting */ nm_ip4_config_merge_setting (config, nm_connection_get_setting_ip4_config (priv->connection), - vpn_routing_metric (connection)); + route_metric); + g_clear_object (&priv->ip4_config); priv->ip4_config = config; nm_ip4_config_export (config); g_object_notify (G_OBJECT (connection), NM_ACTIVE_CONNECTION_IP4_CONFIG); @@ -1223,12 +1314,13 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, GHashTable *config_hash, gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMPlatformIP6Address address; NMIP6Config *config; GValue *val; int i; + guint32 route_metric; nm_log_info (LOGD_VPN, "VPN connection '%s' (IP6 Config Get) reply received.", nm_connection_get_id (priv->connection)); @@ -1280,7 +1372,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, address.plen = g_value_get_uint (val); if (!IN6_IS_ADDR_UNSPECIFIED (&address.address) && address.plen) { - address.source = NM_PLATFORM_SOURCE_VPN; + address.source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (config, &address); } else { nm_log_err (LOGD_VPN, "invalid IP6 config received!"); @@ -1317,6 +1409,8 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, nm_ip6_config_add_domain (config, *domain); } + route_metric = nm_vpn_connection_get_ip6_route_metric (connection); + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES); if (val) { GSList *routes; @@ -1324,15 +1418,15 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, routes = nm_utils_ip6_routes_from_gvalue (val); for (iter = routes; iter; iter = iter->next) { - NMIP6Route *item = iter->data; + NMIPRoute *item = iter->data; NMPlatformIP6Route route; memset (&route, 0, sizeof (route)); - route.network = *nm_ip6_route_get_dest (item); - route.plen = nm_ip6_route_get_prefix (item); - route.gateway = *nm_ip6_route_get_next_hop (item); - route.source = NM_PLATFORM_SOURCE_VPN; - route.metric = vpn_routing_metric (connection); + nm_ip_route_get_dest_binary (item, &route.network); + route.plen = nm_ip_route_get_prefix (item); + nm_ip_route_get_next_hop_binary (item, &route.gateway); + route.source = NM_IP_CONFIG_SOURCE_VPN; + route.metric = route_metric; /* Ignore host routes to the VPN gateway since NM adds one itself * below. Since NM knows more about the routing situation than @@ -1346,7 +1440,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, nm_ip6_config_add_route (config, &route); } - g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref); + g_slist_free_full (routes, (GDestroyNotify) nm_ip_route_unref); } val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT); @@ -1356,8 +1450,9 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, /* Merge in user overrides from the NMConnection's IPv6 setting */ nm_ip6_config_merge_setting (config, nm_connection_get_setting_ip6_config (priv->connection), - vpn_routing_metric (connection)); + route_metric); + g_clear_object (&priv->ip6_config); priv->ip6_config = config; nm_ip6_config_export (config); g_object_notify (G_OBJECT (connection), NM_ACTIVE_CONNECTION_IP6_CONFIG); @@ -1367,8 +1462,8 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, static gboolean connect_timeout_cb (gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); priv->connect_timeout = 0; @@ -1384,9 +1479,9 @@ connect_timeout_cb (gpointer user_data) } static void -connect_success (NMVPNConnection *connection) +connect_success (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); /* 40 second timeout waiting for IP config signal from VPN service */ priv->connect_timeout = g_timeout_add_seconds (40, connect_timeout_cb, connection); @@ -1398,8 +1493,8 @@ connect_success (NMVPNConnection *connection) static void connect_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *err = NULL; nm_log_info (LOGD_VPN, "VPN connection '%s' (Connect) reply received.", @@ -1420,8 +1515,8 @@ connect_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) static void connect_interactive_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *err = NULL; nm_log_info (LOGD_VPN, "VPN connection '%s' (ConnectInteractive) reply received.", @@ -1452,8 +1547,9 @@ static GHashTable * _hash_with_username (NMConnection *connection, const char *username) { NMConnection *dup; - NMSettingVPN *s_vpn; + NMSettingVpn *s_vpn; GHashTable *hash; + GVariant *dict; const char *existing; /* Shortcut if we weren't given a username or if there already was one in @@ -1462,23 +1558,30 @@ _hash_with_username (NMConnection *connection, const char *username) s_vpn = nm_connection_get_setting_vpn (connection); g_assert (s_vpn); existing = nm_setting_vpn_get_user_name (s_vpn); - if (username == NULL || existing) - return nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + if (username == NULL || existing) { + dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); + return hash; + } - dup = nm_connection_duplicate (connection); + dup = nm_simple_connection_new_clone (connection); g_assert (dup); s_vpn = nm_connection_get_setting_vpn (dup); g_assert (s_vpn); g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL); - hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ALL); + dict = nm_connection_to_dbus (dup, NM_CONNECTION_SERIALIZE_ALL); g_object_unref (dup); + + hash = nm_utils_connection_dict_to_hash (dict); + g_variant_unref (dict); return hash; } static void -really_activate (NMVPNConnection *connection, const char *username) +really_activate (NMVpnConnection *connection, const char *username) { - NMVPNConnectionPrivate *priv; + NMVpnConnectionPrivate *priv; NMAgentManager *agent_mgr; GHashTable *details; @@ -1542,15 +1645,20 @@ really_activate (NMVPNConnection *connection, const char *username) } void -nm_vpn_connection_activate (NMVPNConnection *connection) +nm_vpn_connection_activate (NMVpnConnection *connection) { - NMVPNConnectionPrivate *priv; + NMVpnConnectionPrivate *priv; + NMSettingVpn *s_vpn; DBusGConnection *bus; g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + s_vpn = nm_connection_get_setting_vpn (priv->connection); + g_assert (s_vpn); + priv->connection_can_persist = nm_setting_vpn_get_persistent (s_vpn); + _set_vpn_state (connection, STATE_PREPARE, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); @@ -1588,15 +1696,26 @@ nm_vpn_connection_activate (NMVPNConnection *connection) } NMConnection * -nm_vpn_connection_get_connection (NMVPNConnection *connection) +nm_vpn_connection_get_connection (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); return NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection; } -NMVPNConnectionState -nm_vpn_connection_get_vpn_state (NMVPNConnection *connection) +const char* +nm_vpn_connection_get_connection_id (NMVpnConnection *connection) +{ + NMConnection *c; + + g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); + + c = NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection; + return c ? nm_connection_get_id (c) : NULL; +} + +NMVpnConnectionState +nm_vpn_connection_get_vpn_state (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NM_VPN_CONNECTION_STATE_UNKNOWN); @@ -1604,7 +1723,7 @@ nm_vpn_connection_get_vpn_state (NMVPNConnection *connection) } const char * -nm_vpn_connection_get_banner (NMVPNConnection *connection) +nm_vpn_connection_get_banner (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); @@ -1612,7 +1731,7 @@ nm_vpn_connection_get_banner (NMVPNConnection *connection) } NMIP4Config * -nm_vpn_connection_get_ip4_config (NMVPNConnection *connection) +nm_vpn_connection_get_ip4_config (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); @@ -1620,7 +1739,7 @@ nm_vpn_connection_get_ip4_config (NMVPNConnection *connection) } NMIP6Config * -nm_vpn_connection_get_ip6_config (NMVPNConnection *connection) +nm_vpn_connection_get_ip6_config (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); @@ -1628,7 +1747,7 @@ nm_vpn_connection_get_ip6_config (NMVPNConnection *connection) } const char * -nm_vpn_connection_get_ip_iface (NMVPNConnection *connection) +nm_vpn_connection_get_ip_iface (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); @@ -1636,7 +1755,7 @@ nm_vpn_connection_get_ip_iface (NMVPNConnection *connection) } int -nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection) +nm_vpn_connection_get_ip_ifindex (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), -1); @@ -1644,7 +1763,7 @@ nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection) } guint32 -nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection) +nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), 0); @@ -1652,7 +1771,7 @@ nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection) } struct in6_addr * -nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection) +nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), 0); @@ -1660,8 +1779,8 @@ nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection) } void -nm_vpn_connection_disconnect (NMVPNConnection *connection, - NMVPNConnectionStateReason reason, +nm_vpn_connection_disconnect (NMVpnConnection *connection, + NMVpnConnectionStateReason reason, gboolean quitting) { g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); @@ -1670,11 +1789,11 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, } gboolean -nm_vpn_connection_deactivate (NMVPNConnection *connection, - NMVPNConnectionStateReason reason, +nm_vpn_connection_deactivate (NMVpnConnection *connection, + NMVpnConnectionStateReason reason, gboolean quitting) { - NMVPNConnectionPrivate *priv; + NMVpnConnectionPrivate *priv; gboolean success = FALSE; g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), FALSE); @@ -1692,8 +1811,8 @@ nm_vpn_connection_deactivate (NMVPNConnection *connection, static void plugin_need_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *error = NULL; char *setting_name; @@ -1741,11 +1860,13 @@ plugin_need_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_dat static void plugin_new_secrets_cb (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *error = NULL; - if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) { + if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) { + _set_vpn_state (self, STATE_CONNECT, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); + } else { nm_log_err (LOGD_VPN, "(%s/%s) sending new secrets to the plugin failed: %s %s", nm_connection_get_uuid (priv->connection), nm_connection_get_id (priv->connection), @@ -1764,8 +1885,8 @@ get_secrets_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnection *self = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GHashTable *hash; g_return_if_fail (NM_CONNECTION (connection) == priv->connection); @@ -1813,12 +1934,12 @@ get_secrets_cb (NMSettingsConnection *connection, } static void -get_secrets (NMVPNConnection *self, +get_secrets (NMVpnConnection *self, SecretsReq secrets_idx, const char **hints) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_NONE; + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE; GError *error = NULL; g_return_if_fail (secrets_idx < SECRETS_REQ_LAST); @@ -1831,21 +1952,21 @@ get_secrets (NMVPNConnection *self, switch (priv->secrets_idx) { case SECRETS_REQ_SYSTEM: - flags = NM_SETTINGS_GET_SECRETS_FLAG_ONLY_SYSTEM; + flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM; break; case SECRETS_REQ_EXISTING: - flags = NM_SETTINGS_GET_SECRETS_FLAG_NONE; + flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE; break; case SECRETS_REQ_NEW: case SECRETS_REQ_INTERACTIVE: - flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; break; default: g_assert_not_reached (); } if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_USER_REQUESTED; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), @@ -1871,8 +1992,8 @@ plugin_interactive_secrets_required (DBusGProxy *proxy, const char **secrets, gpointer user_data) { - NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVpnConnection *connection = NM_VPN_CONNECTION (user_data); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); guint32 secrets_len = secrets ? g_strv_length ((char **) secrets) : 0; char **hints; guint32 i; @@ -1900,9 +2021,42 @@ plugin_interactive_secrets_required (DBusGProxy *proxy, /******************************************************************************/ static void -nm_vpn_connection_init (NMVPNConnection *self) +device_changed (NMActiveConnection *active, + NMDevice *new_device, + NMDevice *old_device) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (active); + + if (!_service_and_connection_can_persist (NM_VPN_CONNECTION (active))) + return; + if (priv->vpn_state < STATE_CONNECT || priv->vpn_state > STATE_ACTIVATED) + return; + + /* Route-based VPNs must update their routing and send a new IP config + * since all their routes need to be adjusted for new_device. + */ + if (priv->ip_ifindex <= 0) + return; + + /* Device changed underneath the VPN connection. Let the plugin figure + * out that connectivity is down and start its reconnect attempt if it + * needs to. + */ + if (old_device) { + nm_device_set_vpn4_config (old_device, NULL); + nm_device_set_vpn6_config (old_device, NULL); + } + + if (new_device) + apply_parent_device_config (NM_VPN_CONNECTION (active)); +} + +/******************************************************************************/ + +static void +nm_vpn_connection_init (NMVpnConnection *self) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); priv->vpn_state = STATE_WAITING; priv->secrets_idx = SECRETS_REQ_SYSTEM; @@ -1922,7 +2076,7 @@ constructed (GObject *object) static void dispose (GObject *object) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); if (priv->connect_hash) { g_hash_table_destroy (priv->connect_hash); @@ -1953,7 +2107,7 @@ dispose (GObject *object) static void finalize (GObject *object) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); g_free (priv->banner); g_free (priv->ip_iface); @@ -1974,7 +2128,7 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); NMDevice *parent_dev; switch (prop_id) { @@ -2007,12 +2161,12 @@ get_property (GObject *object, guint prop_id, } static void -nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) +nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (connection_class); NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class); - g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate)); + g_type_class_add_private (connection_class, sizeof (NMVpnConnectionPrivate)); /* virtual methods */ object_class->get_property = get_property; @@ -2020,25 +2174,26 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) object_class->dispose = dispose; object_class->finalize = finalize; active_class->device_state_changed = device_state_changed; + active_class->device_changed = device_changed; g_object_class_override_property (object_class, PROP_MASTER, NM_ACTIVE_CONNECTION_MASTER); /* properties */ - g_object_class_install_property (object_class, PROP_VPN_STATE, - g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, - "VpnState", - "Current VPN state", - NM_VPN_CONNECTION_STATE_UNKNOWN, - NM_VPN_CONNECTION_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, PROP_BANNER, - g_param_spec_string (NM_VPN_CONNECTION_BANNER, - "Banner", - "Login Banner", - NULL, - G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VPN_STATE, + g_param_spec_uint (NM_VPN_CONNECTION_VPN_STATE, "", "", + NM_VPN_CONNECTION_STATE_UNKNOWN, + NM_VPN_CONNECTION_STATE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property + (object_class, PROP_BANNER, + g_param_spec_string (NM_VPN_CONNECTION_BANNER, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); g_object_class_override_property (object_class, PROP_IP4_CONFIG, NM_ACTIVE_CONNECTION_IP4_CONFIG); @@ -2060,6 +2215,13 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) 0, NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); + signals[INTERNAL_RETRY_AFTER_FAILURE] = + g_signal_new (NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + nm_dbus_manager_register_exported_type (nm_dbus_manager_get (), G_TYPE_FROM_CLASS (object_class), &dbus_glib_nm_vpn_connection_object_info); diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index c9c88cda..0e63caac 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -19,21 +19,22 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_VPN_CONNECTION_H -#define NM_VPN_CONNECTION_H +#ifndef __NETWORKMANAGER_VPN_CONNECTION_H__ +#define __NETWORKMANAGER_VPN_CONNECTION_H__ #include #include -#include "NetworkManagerVPN.h" +#include "nm-vpn-dbus-interface.h" #include "nm-device.h" #include "nm-auth-subject.h" +#include "nm-active-connection.h" #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) -#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) -#define NM_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) +#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnection)) +#define NM_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) #define NM_IS_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_CONNECTION)) #define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_CONNECTION)) -#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) +#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVpnConnectionClass)) /* Properties */ #define NM_VPN_CONNECTION_VPN_STATE "vpn-state" @@ -41,52 +42,62 @@ /* Signals */ /* not exported: includes old reason code */ -#define NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED "internal-state-changed" +#define NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED "internal-state-changed" +#define NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE "internal-retry-after-failure" -typedef struct { +#define NM_VPN_ROUTE_METRIC_DEFAULT 50 + + +struct _NMVpnConnection { NMActiveConnection parent; -} NMVPNConnection; +}; typedef struct { NMActiveConnectionClass parent; /* Signals */ - void (*vpn_state_changed) (NMVPNConnection *connection, - NMVPNConnectionState new_state, - NMVPNConnectionStateReason reason); + void (*vpn_state_changed) (NMVpnConnection *connection, + NMVpnConnectionState new_state, + NMVpnConnectionStateReason reason); /* not exported over D-Bus */ - void (*internal_state_changed) (NMVPNConnection *connection, - NMVPNConnectionState new_state, - NMVPNConnectionState old_state, - NMVPNConnectionStateReason reason); -} NMVPNConnectionClass; + void (*internal_state_changed) (NMVpnConnection *connection, + NMVpnConnectionState new_state, + NMVpnConnectionState old_state, + NMVpnConnectionStateReason reason); + + void (*internal_failed_retry) (NMVpnConnection *connection); +} NMVpnConnectionClass; GType nm_vpn_connection_get_type (void); -NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, +NMVpnConnection * nm_vpn_connection_new (NMConnection *connection, NMDevice *parent_device, const char *specific_object, NMAuthSubject *subject); -void nm_vpn_connection_activate (NMVPNConnection *connection); -NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection); -NMVPNConnectionState nm_vpn_connection_get_vpn_state (NMVPNConnection *connection); -const char * nm_vpn_connection_get_banner (NMVPNConnection *connection); +void nm_vpn_connection_activate (NMVpnConnection *connection); +NMConnection * nm_vpn_connection_get_connection (NMVpnConnection *connection); +const char* nm_vpn_connection_get_connection_id (NMVpnConnection *connection); +NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *connection); +const char * nm_vpn_connection_get_banner (NMVpnConnection *connection); -gboolean nm_vpn_connection_deactivate (NMVPNConnection *connection, - NMVPNConnectionStateReason reason, +gboolean nm_vpn_connection_deactivate (NMVpnConnection *connection, + NMVpnConnectionStateReason reason, gboolean quitting); -void nm_vpn_connection_disconnect (NMVPNConnection *connection, - NMVPNConnectionStateReason reason, +void nm_vpn_connection_disconnect (NMVpnConnection *connection, + NMVpnConnectionStateReason reason, gboolean quitting); -NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection); -NMIP6Config * nm_vpn_connection_get_ip6_config (NMVPNConnection *connection); -const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection); -int nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection); -guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection); -struct in6_addr * nm_vpn_connection_get_ip6_internal_gateway (NMVPNConnection *connection); +NMIP4Config * nm_vpn_connection_get_ip4_config (NMVpnConnection *connection); +NMIP6Config * nm_vpn_connection_get_ip6_config (NMVpnConnection *connection); +const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *connection); +int nm_vpn_connection_get_ip_ifindex (NMVpnConnection *connection); +guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *connection); +struct in6_addr * nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *connection); + +guint32 nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *connection); +guint32 nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *connection); -#endif /* NM_VPN_CONNECTION_H */ +#endif /* __NETWORKMANAGER_VPN_CONNECTION_H__ */ diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 5550d4d6..1f3798c7 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -19,6 +19,8 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ +#include "config.h" + #include #include @@ -27,36 +29,27 @@ #include "nm-vpn-connection.h" #include "nm-setting-vpn.h" #include "nm-dbus-manager.h" -#include "NetworkManagerVPN.h" +#include "nm-vpn-dbus-interface.h" #include "nm-enum-types.h" #include "nm-logging.h" #define VPN_NAME_FILES_DIR NMCONFDIR "/VPN" -G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMVpnManager, nm_vpn_manager, G_TYPE_OBJECT) -#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate)) +#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVpnManagerPrivate)) typedef struct { GHashTable *services; GFileMonitor *monitor; guint monitor_id; -} NMVPNManagerPrivate; +} NMVpnManagerPrivate; -GQuark -nm_vpn_manager_error_quark (void) -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string ("nm-vpn-manager-error"); - return quark; -} - -static NMVPNService * -get_service_by_namefile (NMVPNManager *self, const char *namefile) +static NMVpnService * +get_service_by_namefile (NMVpnManager *self, const char *namefile) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); GHashTableIter iter; gpointer data; @@ -65,7 +58,7 @@ get_service_by_namefile (NMVPNManager *self, const char *namefile) g_hash_table_iter_init (&iter, priv->services); while (g_hash_table_iter_next (&iter, NULL, &data)) { - NMVPNService *candidate = NM_VPN_SERVICE (data); + NMVpnService *candidate = NM_VPN_SERVICE (data); const char *service_namefile; service_namefile = nm_vpn_service_get_name_file (candidate); @@ -76,13 +69,13 @@ get_service_by_namefile (NMVPNManager *self, const char *namefile) } gboolean -nm_vpn_manager_activate_connection (NMVPNManager *manager, - NMVPNConnection *vpn, +nm_vpn_manager_activate_connection (NMVpnManager *manager, + NMVpnConnection *vpn, GError **error) { NMConnection *connection; - NMSettingVPN *s_vpn; - NMVPNService *service; + NMSettingVpn *s_vpn; + NMVpnService *service; const char *service_name; NMDevice *device; @@ -95,7 +88,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, g_assert (device); if ( nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED && nm_device_get_state (device) != NM_DEVICE_STATE_SECONDARIES) { - g_set_error_literal (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The base device for the VPN connection was not active."); return FALSE; } @@ -109,7 +102,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, g_assert (service_name); service = g_hash_table_lookup (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name); if (!service) { - g_set_error (error, NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID, + g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, "The VPN service '%s' was not installed.", service_name); return FALSE; @@ -119,18 +112,18 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, } gboolean -nm_vpn_manager_deactivate_connection (NMVPNManager *self, - NMVPNConnection *connection, - NMVPNConnectionStateReason reason) +nm_vpn_manager_deactivate_connection (NMVpnManager *self, + NMVpnConnection *connection, + NMVpnConnectionStateReason reason) { return nm_vpn_connection_deactivate (connection, reason, FALSE); } static void -try_add_service (NMVPNManager *self, const char *namefile) +try_add_service (NMVpnManager *self, const char *namefile) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); - NMVPNService *service = NULL; + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + NMVpnService *service = NULL; GHashTableIter iter; GError *error = NULL; const char *service_name; @@ -166,9 +159,9 @@ vpn_dir_changed (GFileMonitor *monitor, GFileMonitorEvent event_type, gpointer user_data) { - NMVPNManager *self = NM_VPN_MANAGER (user_data); - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); - NMVPNService *service; + NMVpnManager *self = NM_VPN_MANAGER (user_data); + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + NMVpnService *service; char *path; path = g_file_get_path (file); @@ -207,10 +200,10 @@ vpn_dir_changed (GFileMonitor *monitor, /******************************************************************************/ -NMVPNManager * +NMVpnManager * nm_vpn_manager_get (void) { - static NMVPNManager *singleton = NULL; + static NMVpnManager *singleton = NULL; if (!singleton) singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL)); @@ -222,9 +215,9 @@ nm_vpn_manager_get (void) } static void -nm_vpn_manager_init (NMVPNManager *self) +nm_vpn_manager_init (NMVpnManager *self) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); GFile *file; GDir *dir; const char *fn; @@ -258,11 +251,11 @@ nm_vpn_manager_init (NMVPNManager *self) } static void -stop_all_services (NMVPNManager *self) +stop_all_services (NMVpnManager *self) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self); GHashTableIter iter; - NMVPNService *service; + NMVpnService *service; g_hash_table_iter_init (&iter, priv->services); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) { @@ -275,7 +268,7 @@ stop_all_services (NMVPNManager *self) static void dispose (GObject *object) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); + NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); if (priv->monitor) { if (priv->monitor_id) @@ -294,15 +287,13 @@ dispose (GObject *object) } static void -nm_vpn_manager_class_init (NMVPNManagerClass *manager_class) +nm_vpn_manager_class_init (NMVpnManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate)); + g_type_class_add_private (manager_class, sizeof (NMVpnManagerPrivate)); /* virtual methods */ object_class->dispose = dispose; - - dbus_g_error_domain_register (NM_VPN_MANAGER_ERROR, NULL, NM_TYPE_VPN_MANAGER_ERROR); } diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index 57f947b0..b75a6179 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -19,52 +19,38 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef NM_VPN_MANAGER_H -#define NM_VPN_MANAGER_H +#ifndef __NETWORKMANAGER_VPN_MANAGER_H__ +#define __NETWORKMANAGER_VPN_MANAGER_H__ #include #include #include "nm-vpn-connection.h" #define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) -#define NM_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager)) -#define NM_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVPNManagerClass)) +#define NM_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVpnManager)) +#define NM_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVpnManagerClass)) #define NM_IS_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_MANAGER)) #define NM_IS_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_MANAGER)) -#define NM_VPN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVPNManagerClass)) - -typedef enum -{ - NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0, /*< nick=BaseDeviceNotActive >*/ - NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, /*< nick=ConnectionInvalid >*/ - NM_VPN_MANAGER_ERROR_SERVICE_INVALID, /*< nick=ServiceInvalid >*/ - NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, /*< nick=ServiceStartFailed >*/ -} NMVPNManagerError; - -#define NM_VPN_MANAGER_ERROR (nm_vpn_manager_error_quark ()) - -GQuark nm_vpn_manager_error_quark (void); -GType nm_vpn_manager_error_get_type (void); - +#define NM_VPN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVpnManagerClass)) typedef struct { GObject parent; -} NMVPNManager; +} NMVpnManager; typedef struct { GObjectClass parent; -} NMVPNManagerClass; +} NMVpnManagerClass; GType nm_vpn_manager_get_type (void); -NMVPNManager *nm_vpn_manager_get (void); +NMVpnManager *nm_vpn_manager_get (void); -gboolean nm_vpn_manager_activate_connection (NMVPNManager *manager, - NMVPNConnection *vpn, +gboolean nm_vpn_manager_activate_connection (NMVpnManager *manager, + NMVpnConnection *vpn, GError **error); -gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, - NMVPNConnection *connection, - NMVPNConnectionStateReason reason); +gboolean nm_vpn_manager_deactivate_connection (NMVpnManager *manager, + NMVpnConnection *connection, + NMVpnConnectionStateReason reason); -#endif /* NM_VPN_MANAGER_H */ +#endif /* __NETWORKMANAGER_VPN_MANAGER_H__ */ diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index 824543fa..b46d13ec 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -19,10 +19,10 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ -#include +#include "config.h" + #include #include -#include #include #include #include @@ -35,7 +35,7 @@ #include "nm-vpn-manager.h" #include "nm-glib-compat.h" -G_DEFINE_TYPE (NMVPNService, nm_vpn_service, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMVpnService, nm_vpn_service, G_TYPE_OBJECT) typedef struct { char *name; @@ -43,24 +43,24 @@ typedef struct { char *program; char *namefile; - NMVPNConnection *active; + NMVpnConnection *active; GSList *pending; guint start_timeout; gboolean service_running; -} NMVPNServicePrivate; +} NMVpnServicePrivate; -#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVPNServicePrivate)) +#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVpnServicePrivate)) #define VPN_CONNECTION_GROUP "VPN Connection" -static gboolean start_pending_vpn (NMVPNService *self); +static gboolean start_pending_vpn (NMVpnService *self, GError **error); -NMVPNService * +NMVpnService * nm_vpn_service_new (const char *namefile, GError **error) { - NMVPNService *self; - NMVPNServicePrivate *priv; + NMVpnService *self; + NMVpnServicePrivate *priv; GKeyFile *kf; g_return_val_if_fail (namefile != NULL, NULL); @@ -72,7 +72,7 @@ nm_vpn_service_new (const char *namefile, GError **error) return NULL; } - self = (NMVPNService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL); + self = (NMVpnService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL); priv = NM_VPN_SERVICE_GET_PRIVATE (self); priv->namefile = g_strdup (namefile); @@ -100,7 +100,7 @@ error: } const char * -nm_vpn_service_get_dbus_service (NMVPNService *service) +nm_vpn_service_get_dbus_service (NMVpnService *service) { g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL); @@ -108,7 +108,7 @@ nm_vpn_service_get_dbus_service (NMVPNService *service) } const char * -nm_vpn_service_get_name_file (NMVPNService *service) +nm_vpn_service_get_name_file (NMVpnService *service) { g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL); @@ -116,21 +116,21 @@ nm_vpn_service_get_name_file (NMVPNService *service) } static void -connection_vpn_state_changed (NMVPNConnection *connection, - NMVPNConnectionState new_state, - NMVPNConnectionState old_state, - NMVPNConnectionStateReason reason, +connection_vpn_state_changed (NMVpnConnection *connection, + NMVpnConnectionState new_state, + NMVpnConnectionState old_state, + NMVpnConnectionStateReason reason, gpointer user_data) { - NMVPNService *self = NM_VPN_SERVICE (user_data); - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); + NMVpnService *self = NM_VPN_SERVICE (user_data); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); if (new_state == NM_VPN_CONNECTION_STATE_FAILED || new_state == NM_VPN_CONNECTION_STATE_DISCONNECTED) { g_signal_handlers_disconnect_by_func (connection, G_CALLBACK (connection_vpn_state_changed), self); if (connection == priv->active) { priv->active = NULL; - start_pending_vpn (self); + start_pending_vpn (self, NULL); } else priv->pending = g_slist_remove (priv->pending, connection); g_object_unref (connection); @@ -138,11 +138,11 @@ connection_vpn_state_changed (NMVPNConnection *connection, } void -nm_vpn_service_stop_connections (NMVPNService *service, +nm_vpn_service_stop_connections (NMVpnService *service, gboolean quitting, - NMVPNConnectionStateReason reason) + NMVpnConnectionStateReason reason) { - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); GSList *iter; /* Just add priv->active to the beginning of priv->pending, @@ -154,7 +154,7 @@ nm_vpn_service_stop_connections (NMVPNService *service, } for (iter = priv->pending; iter; iter = iter->next) { - NMVPNConnection *vpn = NM_VPN_CONNECTION (iter->data); + NMVpnConnection *vpn = NM_VPN_CONNECTION (iter->data); g_signal_handlers_disconnect_by_func (vpn, G_CALLBACK (connection_vpn_state_changed), service); if (quitting) { @@ -184,8 +184,8 @@ _daemon_setup (gpointer user_data G_GNUC_UNUSED) static gboolean _daemon_exec_timeout (gpointer data) { - NMVPNService *self = NM_VPN_SERVICE (data); - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); + NMVpnService *self = NM_VPN_SERVICE (data); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", priv->name); priv->start_timeout = 0; @@ -194,9 +194,9 @@ _daemon_exec_timeout (gpointer data) } static gboolean -nm_vpn_service_daemon_exec (NMVPNService *service, GError **error) +nm_vpn_service_daemon_exec (NMVpnService *service, GError **error) { - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); GPid pid; char *vpn_argv[2]; gboolean success = FALSE; @@ -219,7 +219,7 @@ nm_vpn_service_daemon_exec (NMVPNService *service, GError **error) spawn_error && spawn_error->message ? spawn_error->message : "(unknown)"); g_set_error (error, - NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_START_FAILED, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "%s", spawn_error ? spawn_error->message : "unknown g_spawn_async() error"); nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_FAILED); @@ -231,9 +231,9 @@ nm_vpn_service_daemon_exec (NMVPNService *service, GError **error) } static gboolean -start_active_vpn (NMVPNService *self, GError **error) +start_active_vpn (NMVpnService *self, GError **error) { - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); if (!priv->active) return TRUE; @@ -253,9 +253,9 @@ start_active_vpn (NMVPNService *self, GError **error) } static gboolean -start_pending_vpn (NMVPNService *self) +start_pending_vpn (NMVpnService *self, GError **error) { - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); g_assert (priv->active == NULL); @@ -266,15 +266,15 @@ start_pending_vpn (NMVPNService *self) priv->active = g_slist_nth_data (priv->pending, 0); priv->pending = g_slist_remove (priv->pending, priv->active); - return start_active_vpn (self, NULL); + return start_active_vpn (self, error); } gboolean -nm_vpn_service_activate (NMVPNService *service, - NMVPNConnection *vpn, +nm_vpn_service_activate (NMVpnService *service, + NMVpnConnection *vpn, GError **error) { - NMVPNServicePrivate *priv; + NMVpnServicePrivate *priv; g_return_val_if_fail (NM_IS_VPN_SERVICE (service), FALSE); g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE); @@ -300,7 +300,7 @@ nm_vpn_service_activate (NMVPNService *service, } /* Otherwise start the next VPN */ - return start_pending_vpn (service); + return start_pending_vpn (service, error); } static void @@ -310,8 +310,8 @@ _name_owner_changed (NMDBusManager *mgr, const char *new, gpointer user_data) { - NMVPNService *service = NM_VPN_SERVICE (user_data); - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); + NMVpnService *service = NM_VPN_SERVICE (user_data); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service); gboolean old_owner_good, new_owner_good, success; if (strcmp (name, priv->dbus_service)) @@ -344,7 +344,7 @@ _name_owner_changed (NMDBusManager *mgr, /******************************************************************************/ static void -nm_vpn_service_init (NMVPNService *self) +nm_vpn_service_init (NMVpnService *self) { g_signal_connect (nm_dbus_manager_get (), NM_DBUS_MANAGER_NAME_OWNER_CHANGED, @@ -355,8 +355,8 @@ nm_vpn_service_init (NMVPNService *self) static void dispose (GObject *object) { - NMVPNService *self = NM_VPN_SERVICE (object); - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); + NMVpnService *self = NM_VPN_SERVICE (object); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); if (priv->start_timeout) { g_source_remove (priv->start_timeout); @@ -377,7 +377,7 @@ dispose (GObject *object) static void finalize (GObject *object) { - NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object); + NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object); g_free (priv->name); g_free (priv->dbus_service); @@ -388,11 +388,11 @@ finalize (GObject *object) } static void -nm_vpn_service_class_init (NMVPNServiceClass *service_class) +nm_vpn_service_class_init (NMVpnServiceClass *service_class) { GObjectClass *object_class = G_OBJECT_CLASS (service_class); - g_type_class_add_private (service_class, sizeof (NMVPNServicePrivate)); + g_type_class_add_private (service_class, sizeof (NMVpnServicePrivate)); /* virtual methods */ object_class->dispose = dispose; diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h index 4545d1f0..cafa6904 100644 --- a/src/vpn-manager/nm-vpn-service.h +++ b/src/vpn-manager/nm-vpn-service.h @@ -19,8 +19,8 @@ * Copyright (C) 2005 - 2008 Novell, Inc. */ -#ifndef NM_VPN_SERVICE_H -#define NM_VPN_SERVICE_H +#ifndef __NETWORKMANAGER_VPN_SERVICE_H__ +#define __NETWORKMANAGER_VPN_SERVICE_H__ #include #include @@ -28,36 +28,36 @@ #include "nm-vpn-connection.h" #define NM_TYPE_VPN_SERVICE (nm_vpn_service_get_type ()) -#define NM_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVPNService)) -#define NM_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVPNServiceClass)) +#define NM_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVpnService)) +#define NM_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVpnServiceClass)) #define NM_IS_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE)) #define NM_IS_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_SERVICE)) -#define NM_VPN_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVPNServiceClass)) +#define NM_VPN_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVpnServiceClass)) typedef struct { GObject parent; -} NMVPNService; +} NMVpnService; typedef struct { GObjectClass parent; -} NMVPNServiceClass; +} NMVpnServiceClass; GType nm_vpn_service_get_type (void); -NMVPNService * nm_vpn_service_new (const char *namefile, GError **error); +NMVpnService * nm_vpn_service_new (const char *namefile, GError **error); /* Returns the VPN service's D-Bus service name */ -const char *nm_vpn_service_get_dbus_service (NMVPNService *service); +const char *nm_vpn_service_get_dbus_service (NMVpnService *service); /* Returns the path of the VPN service's .name file */ -const char *nm_vpn_service_get_name_file (NMVPNService *service); +const char *nm_vpn_service_get_name_file (NMVpnService *service); -gboolean nm_vpn_service_activate (NMVPNService *service, - NMVPNConnection *vpn, +gboolean nm_vpn_service_activate (NMVpnService *service, + NMVpnConnection *vpn, GError **error); -void nm_vpn_service_stop_connections (NMVPNService *service, +void nm_vpn_service_stop_connections (NMVpnService *service, gboolean quitting, - NMVPNConnectionStateReason reason); + NMVpnConnectionStateReason reason); #endif /* NM_VPN_VPN_SERVICE_H */ -- cgit 1.3.0-6-gf8a5