From fb6dddd20cf37b6ceec015c58dd7c48da95a3f3b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 13 Sep 2013 13:11:15 -0500 Subject: [PATCH 01/15] Update to git snapshot --- .gitignore | 1 + NetworkManager.spec | 81 ++++++++++++++++++++++++++++----------------- sources | 2 +- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index eff6012..4cd0f74 100644 --- a/.gitignore +++ b/.gitignore @@ -293,3 +293,4 @@ network-manager-applet-0.8.1.tar.bz2 /NetworkManager-0.9.9.0.git20130603.tar.bz2 /NetworkManager-0.9.9.0.git20130724.tar.bz2 /NetworkManager-0.9.9.0.git20130807.tar.bz2 +/NetworkManager-0.9.9.0.git20130913.tar.bz2 diff --git a/NetworkManager.spec b/NetworkManager.spec index 937da28..bcf5b66 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -2,22 +2,16 @@ %define dbus_glib_version 0.94 %define glib2_version 2.24.0 -%define wireless_tools_version 1:28-0pre9 %define libnl3_version 3.2.7 %define ppp_version 2.4.5 -%define snapshot .git20130807 +%define snapshot .git20130913 %define realversion 0.9.9.0 %global regen_docs 0 -%if 0%{?fedora} && 0%{?fedora} < 17 -%define systemd_dir /lib/systemd/system -%define udev_dir /lib/udev -%else %define systemd_dir %{_prefix}/lib/systemd/system %define udev_dir %{_prefix}/lib/udev -%endif %global _hardened_build 1 @@ -25,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 9%{snapshot}%{?dist} +Release: 11%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -37,8 +31,6 @@ Patch1: explain-dns1-dns2.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires(post): chkconfig -Requires(preun): chkconfig Requires(post): systemd-sysv Requires(post): systemd Requires(preun): systemd @@ -67,7 +59,9 @@ Conflicts: kde-plasma-networkmanagement < 1:0.9-0.49.20110527git.nm09 BuildRequires: dbus-devel >= %{dbus_version} BuildRequires: dbus-glib-devel >= %{dbus_glib_version} -BuildRequires: wireless-tools-devel >= %{wireless_tools_version} +%if 0%{?fedora} +BuildRequires: wireless-tools-devel >= 1:28-0pre9 +%endif BuildRequires: glib2-devel >= %{glib2_version} BuildRequires: gobject-introspection-devel >= 0.10.3 BuildRequires: gettext-devel @@ -97,12 +91,9 @@ BuildRequires: wimax-devel %endif %endif BuildRequires: systemd >= 200-3 systemd-devel -%if 0%{?fedora} && 0%{?fedora} < 17 -# systemd.pc is in systemd-units for F16 and below -BuildRequires: systemd-units -%endif BuildRequires: libsoup-devel -BuildRequires: libndp-devel >= 0.1-3 +BuildRequires: libndp-devel >= 1.0 +BuildRequires: ModemManager-glib-devel >= 1.0 %description NetworkManager is a system network service that manages your network devices @@ -200,6 +191,7 @@ deployments. --with-crypto=nss \ --enable-more-warnings=error \ --enable-ppp=yes \ + --with-modem-manager-1=yes \ --enable-vala=yes \ %if ! 0%{?rhel} %ifnarch s390 s390x @@ -208,6 +200,11 @@ deployments. %endif %if %{regen_docs} --enable-gtk-doc \ +%endif +%if 0%{?fedora} + --with-wext=yes \ +%else + --with-wext=no \ %endif --enable-polkit=yes \ --enable-modify-system=yes \ @@ -287,21 +284,6 @@ fi %postun %systemd_postun -%triggerun -- NetworkManager < 1:0.8.990 -# Save the current service runlevel info -# User must manually run systemd-sysv-convert --apply NetworkManager -# to migrate them to systemd targets -/usr/bin/systemd-sysv-convert --save NetworkManager >/dev/null 2>&1 ||: -/bin/systemctl --no-reload enable NetworkManager.service >/dev/null 2>&1 ||: -# Run these because the SysV package being removed won't do them -/sbin/chkconfig --del NetworkManager >/dev/null 2>&1 || : -/bin/systemctl try-restart NetworkManager.service >/dev/null 2>&1 || : - - -%triggerun -- NetworkManager < 1:0.7.0-0.9.2.svn3614 -/sbin/service NetworkManagerDispatcher stop >/dev/null 2>&1 -/sbin/chkconfig --del NetworkManagerDispatcher -exit 0 %post glib -p /sbin/ldconfig %postun glib -p /sbin/ldconfig @@ -400,6 +382,43 @@ exit 0 %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Fri Sep 13 2013 Dan Williams - 0.9.9.0-11.git20130913 +- core: actually enable ModemManager 1.0 support +- libnm-glib: fix nm_remote_connection_delete() not calling callback (rh #997568) +- cli: ensure terminal is reset after quitting +- cli: set wep-key-type properly when editing (rh #1003945) +- man: fix typo in nmcli examples manpage (rh #1004117) +- core: fix setting VLAN ingress/egress mappings +- core: allow creating VLANs from interfaces other than Ethernet (rh #1003180) +- cli: fix input/output format conversion (rh #998929) + +* Fri Sep 6 2013 Dan Williams - 0.9.9.0-10.git20130906 +- core: fix bug which disallowed deleting connections (rh #997568) +- core: add support for Team devices +- core: enable NetworkManager-wait-online by default (rh #816655) +- core: fix crash when 'gre' and 'macvlan' links change (rh #997396) +- core: fail activation when invalid static routes are configured (rh #999544) +- core: enhance connectivity checking to include portal detection +- core: allow hyphens for MAC addresses (rh #1002553) +- core: remove NetworkManager-created software devices when they are deactivated (rh #953300) +- core: fix handling of some DHCP client identifiers (rh #999503) +- core: correctly handle Open vSwitch interfaces as generic interfaces (rh #1004356) +- core: better handle Layer-2-only connections (rh #979288) +- cli: enhanced bash completion +- cli: make the 'describe' command more visible (rh #998002) +- cli: fix bug rejecting changes to Wi-Fi channels (rh #999999) +- cli: update bash completion to suggest connection names (rh #997997) +- cli: fix tab completion for aliases in edit mode +- cli: ask whether to switch IP method to 'auto' when all addresses are deleted (rh #998137) +- cli: request missing information when --ask is passed (rh #953291) +- cli: add 'remove' command to edit mode +- cli: fix creation of secure Wi-Fi connections (rh #997969) (rh #997555) +- cli: default autoconnect to no and ask whether to activate on save (rh #953296) +- man: clarify manpage text (rh #960071) (rh #953299) +- man: fix errors in the nmcli help output and manpage (rh #997566) +- ifcfg-rh: only write IPV6_DEFAULTGW when there's actually a default gateway (rh #997759) +- ifcfg-rh: fix handling of legacy-format routes file with missing gateway + * Wed Aug 7 2013 Dan Williams - 0.9.9.0-9.git20130807 - core: fix assert on multi-hop routes (rh #989022) - core: fix dispatcher systemd unit enabling (rh #948433) diff --git a/sources b/sources index a5630ff..ca3e760 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -5fc69f085230e4ae4330ad82dfe485fa NetworkManager-0.9.9.0.git20130807.tar.bz2 +bb22ef6997c61e2039eb1e7b7fd965d7 NetworkManager-0.9.9.0.git20130913.tar.bz2 From c62496993320d39fe6f60e526d962a70bd519fb1 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Fri, 20 Sep 2013 10:02:52 -0500 Subject: [PATCH 02/15] Drop wimax. --- NetworkManager.spec | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/NetworkManager.spec b/NetworkManager.spec index bcf5b66..ea6fd1a 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 11%{snapshot}%{?dist} +Release: 12%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -84,12 +84,6 @@ BuildRequires: libuuid-devel BuildRequires: libgudev1-devel >= 143 BuildRequires: vala-tools BuildRequires: iptables -# No wimax or bluetooth on s390 -%if ! 0%{?rhel} -%ifnarch s390 s390x -BuildRequires: wimax-devel -%endif -%endif BuildRequires: systemd >= 200-3 systemd-devel BuildRequires: libsoup-devel BuildRequires: libndp-devel >= 1.0 @@ -102,21 +96,6 @@ It manages ethernet, WiFi, mobile broadband (WWAN), and PPPoE devices, and provides VPN integration with a variety of different VPN services. -%if ! 0%{?rhel} -%ifnarch s390 s390x -%package wimax -Summary: Intel WiMAX device support for NetworkManager -Group: System Environment/Base -Requires: wimax -Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} - -%description wimax -This package contains NetworkManager support for Intel WiMAX mobile broadband -devices. -%endif -%endif - - %package devel Summary: Libraries and headers for adding NetworkManager support to applications Group: Development/Libraries @@ -193,11 +172,6 @@ deployments. --enable-ppp=yes \ --with-modem-manager-1=yes \ --enable-vala=yes \ -%if ! 0%{?rhel} -%ifnarch s390 s390x - --enable-wimax=yes \ -%endif -%endif %if %{regen_docs} --enable-gtk-doc \ %endif @@ -327,14 +301,6 @@ fi %{systemd_dir}/network-online.target.wants/NetworkManager-wait-online.service %{_datadir}/doc/NetworkManager/examples/server.conf -%if ! 0%{?rhel} -%ifnarch s390 s390x -%files wimax -%defattr(-,root,root,0755) -%{_libdir}/%{name}/libnm-device-plugin-wimax.so -%endif -%endif - %files devel %defattr(-,root,root,0755) %doc ChangeLog docs/api/html/* @@ -382,6 +348,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Fri Sep 20 2013 Bill Nottingham - 0.9.9.0-12.git20130913 +- drop wimax subpackage + * Fri Sep 13 2013 Dan Williams - 0.9.9.0-11.git20130913 - core: actually enable ModemManager 1.0 support - libnm-glib: fix nm_remote_connection_delete() not calling callback (rh #997568) From afa35614d0b3127cd02a1ccae795da5c442fe72f Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 1 Oct 2013 10:55:07 -0400 Subject: [PATCH 03/15] Update to git snapshot --- .gitignore | 1 + NetworkManager.spec | 22 ++++++++++++++++++++-- sources | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 4cd0f74..8b91730 100644 --- a/.gitignore +++ b/.gitignore @@ -294,3 +294,4 @@ network-manager-applet-0.8.1.tar.bz2 /NetworkManager-0.9.9.0.git20130724.tar.bz2 /NetworkManager-0.9.9.0.git20130807.tar.bz2 /NetworkManager-0.9.9.0.git20130913.tar.bz2 +/NetworkManager-0.9.9.0.git20131001.tar.bz2 diff --git a/NetworkManager.spec b/NetworkManager.spec index ea6fd1a..5b7434a 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -5,7 +5,7 @@ %define libnl3_version 3.2.7 %define ppp_version 2.4.5 -%define snapshot .git20130913 +%define snapshot .git20131001 %define realversion 0.9.9.0 %global regen_docs 0 @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 12%{snapshot}%{?dist} +Release: 13%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -348,6 +348,24 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Tue Oct 1 2013 Dan Winship - 0.9.9.0-13.git20131001 +- core: fix bridge device creation (#1012532) +- core,settings: do not call functions with connection==NULL (rh #1008151) +- cli: accept gateway in the IP questionnaire of 'nmcli -a con add' (rh #1007368) +- cli: always print success message (not only in --pretty mode) (rh #1006444) +- cli: fix bond questionnaire to be able to set miimon (rh #1007355) +- ifcfg-rh: if IPv4 is disabled put DNS domains (DOMAIN) into IPv6 (rh #1004866) +- platform: fix a crash when nm_platform_sysctl_get() returns NULL (rh #1010522) +- platform: fix InfiniBand partition handling (rh #1008568) +- infiniband: only check the last 8 bytes when doing hwaddr matches (rh #1008566) +- bluez: merge adding support for BlueZ 5 (bgo #701078) +- api: clarify lifetime and behavior of ActiveConnection's SpecificObject property (rh #1012309) +- vpn: fix connecting to VPN (bgo #708255) +- rdisc: do not crash on NDP init failures (rh #1012151) +- cli: be more verbose when adding IP addresses in questionnaire (rh #1006450) +- team: chain up parent dispose() in NMDeviceTeam dispose() (rh #1013593) +- translation updates + * Fri Sep 20 2013 Bill Nottingham - 0.9.9.0-12.git20130913 - drop wimax subpackage diff --git a/sources b/sources index ca3e760..9c25430 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -bb22ef6997c61e2039eb1e7b7fd965d7 NetworkManager-0.9.9.0.git20130913.tar.bz2 +8d754e04a35b9cb476b063d91eb9bdaa NetworkManager-0.9.9.0.git20131001.tar.bz2 From f40b011443e2a7bdf974f04a3c110a75f97b57ab Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 3 Oct 2013 14:14:28 -0500 Subject: [PATCH 04/15] Update snapshot --- .gitignore | 1 + NetworkManager.spec | 16 +++++++++++++--- sources | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 8b91730..778ec86 100644 --- a/.gitignore +++ b/.gitignore @@ -295,3 +295,4 @@ network-manager-applet-0.8.1.tar.bz2 /NetworkManager-0.9.9.0.git20130807.tar.bz2 /NetworkManager-0.9.9.0.git20130913.tar.bz2 /NetworkManager-0.9.9.0.git20131001.tar.bz2 +/NetworkManager-0.9.9.0.git20131003.tar.bz2 diff --git a/NetworkManager.spec b/NetworkManager.spec index 5b7434a..fd24237 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -5,7 +5,7 @@ %define libnl3_version 3.2.7 %define ppp_version 2.4.5 -%define snapshot .git20131001 +%define snapshot .git20131003 %define realversion 0.9.9.0 %global regen_docs 0 @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 13%{snapshot}%{?dist} +Release: 14%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -171,6 +171,8 @@ deployments. --enable-more-warnings=error \ --enable-ppp=yes \ --with-modem-manager-1=yes \ + --enable-bluez4=no \ + --enable-wimax=no \ --enable-vala=yes \ %if %{regen_docs} --enable-gtk-doc \ @@ -348,6 +350,14 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Thu Oct 3 2013 Dan Williams - 0.9.9.0-14.git20131003 +- core: fix DHCPv6 address prefix length (rh #1013583) +- cli: enhance bonding questionaire (rh #1007355) +- core: fix crash with Bluez5 if PAN connection is not defined (rh #1014770) +- libnm-glib: fix various memory leaks that could cause UIs to mis-report state +- core: fix issues with mis-configured IPv6 router advertisements (rh #1008104) +- cli: fix potential crash editing connections (rh #1011942) + * Tue Oct 1 2013 Dan Winship - 0.9.9.0-13.git20131001 - core: fix bridge device creation (#1012532) - core,settings: do not call functions with connection==NULL (rh #1008151) @@ -360,7 +370,7 @@ fi - infiniband: only check the last 8 bytes when doing hwaddr matches (rh #1008566) - bluez: merge adding support for BlueZ 5 (bgo #701078) - api: clarify lifetime and behavior of ActiveConnection's SpecificObject property (rh #1012309) -- vpn: fix connecting to VPN (bgo #708255) +- vpn: fix connecting to VPN (bgo #708255) (rh #1014716) - rdisc: do not crash on NDP init failures (rh #1012151) - cli: be more verbose when adding IP addresses in questionnaire (rh #1006450) - team: chain up parent dispose() in NMDeviceTeam dispose() (rh #1013593) diff --git a/sources b/sources index 9c25430..b82a9f6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -8d754e04a35b9cb476b063d91eb9bdaa NetworkManager-0.9.9.0.git20131001.tar.bz2 +7251704430cb206f2c29bfebc45bd0fb NetworkManager-0.9.9.0.git20131003.tar.bz2 From f2061f25cc84c8fa35f063d95e3a6f100bf364ec Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 30 Oct 2013 11:57:44 -0500 Subject: [PATCH 05/15] Note that 1023571 is fixed upstream for next snapshot --- NetworkManager.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NetworkManager.spec b/NetworkManager.spec index fd24237..d0157fb 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -350,6 +350,8 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +1023571 got fixed in git master on 2013-10-29 + * Thu Oct 3 2013 Dan Williams - 0.9.9.0-14.git20131003 - core: fix DHCPv6 address prefix length (rh #1013583) - cli: enhance bonding questionaire (rh #1007355) From 1c5320e921942f3ed5994e86a85c48979b87fa2a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Oct 2013 18:17:46 +0100 Subject: [PATCH 06/15] add notes to %changelog about upcomming fixes in F20 --- NetworkManager.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NetworkManager.spec b/NetworkManager.spec index d0157fb..5e8e39d 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -350,7 +350,8 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog -1023571 got fixed in git master on 2013-10-29 +#- core: fix crash in ifcfg-rh plugin when reloading connections (rh #1023571) +#- core: fix crash when having connections with NEVER_DEFAULT (rh #1021112) * Thu Oct 3 2013 Dan Williams - 0.9.9.0-14.git20131003 - core: fix DHCPv6 address prefix length (rh #1013583) From d3cdc3cf7f6bda3f7aed6f29f414fd2f90ca7f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Fri, 8 Nov 2013 12:58:26 +0100 Subject: [PATCH 07/15] Include the patches for following bugs (mostly crashes): rh #1021112 rh #1023571 rh #1019021 rh #1025007 rh #1012151 --- NetworkManager.spec | 20 ++++++-- rh1012151-ipv6-disable.patch | 27 ++++++++++ rh1019021-fix-crash-ip6-routing.patch | 62 +++++++++++++++++++++++ rh1021112-fix-crash-never-default.patch | 19 +++++++ rh1023571-fix-crash-ifcfg-rh-reload.patch | 55 ++++++++++++++++++++ rh1025007-fix-crash-ifcfg-rh.patch | 35 +++++++++++++ 6 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 rh1012151-ipv6-disable.patch create mode 100644 rh1019021-fix-crash-ip6-routing.patch create mode 100644 rh1021112-fix-crash-never-default.patch create mode 100644 rh1023571-fix-crash-ifcfg-rh-reload.patch create mode 100644 rh1025007-fix-crash-ifcfg-rh.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 5e8e39d..18b1bf4 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 14%{snapshot}%{?dist} +Release: 15%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -28,6 +28,11 @@ Source: %{name}-%{realversion}%{snapshot}.tar.bz2 Source1: NetworkManager.conf Source2: 00-server.conf Patch1: explain-dns1-dns2.patch +Patch2: rh1023571-fix-crash-ifcfg-rh-reload.patch +Patch3: rh1021112-fix-crash-never-default.patch +Patch4: rh1019021-fix-crash-ip6-routing.patch +Patch5: rh1025007-fix-crash-ifcfg-rh.patch +Patch6: rh1012151-ipv6-disable.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -152,6 +157,11 @@ deployments. %setup -q -n NetworkManager-%{realversion} %patch1 -p1 -b .explain-dns1-dns2 +%patch2 -p1 -b .patch2 +%patch3 -p1 -b .patch3 +%patch4 -p1 -b .patch4 +%patch5 -p1 -b .patch5 +%patch6 -p1 -b .patch6 %build @@ -350,8 +360,12 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog -#- core: fix crash in ifcfg-rh plugin when reloading connections (rh #1023571) -#- core: fix crash when having connections with NEVER_DEFAULT (rh #1021112) +* Fri Nov 8 2013 Jiří Klimeš - 0.9.9.0-15.git20131003 +- ifcfg-rh: fix crash in ifcfg-rh plugin when reloading connections (rh #1023571) +- ifcfg-rh: fix crash when having connections with NEVER_DEFAULT (rh #1021112) +- core: fix segfault in nm-policy when setting default route for vpn (rh #1019021) +- ifcfg-rh: fix crash when reading connection (assert) (rh #1025007) +- core: allow IPv4 to proceed if IPv6 is globally disabled but set to "auto" (rh #1012151) * Thu Oct 3 2013 Dan Williams - 0.9.9.0-14.git20131003 - core: fix DHCPv6 address prefix length (rh #1013583) diff --git a/rh1012151-ipv6-disable.patch b/rh1012151-ipv6-disable.patch new file mode 100644 index 0000000..884c721 --- /dev/null +++ b/rh1012151-ipv6-disable.patch @@ -0,0 +1,27 @@ +commit 9543e45afe0746ac1c9c10e4f78f43264fd288b4 +Author: Dan Williams +Date: Mon Oct 7 11:40:16 2013 -0500 + + core: allow IPv4 to proceed if IPv6 is globally disabled but set to "auto" (rh #1012151) + + If the user disabled IPv6 support in the kernel with "ipv6.disable=1" on the + kernel boot line, then any attempts to open IPv6 sockets (which libndp does) + will fail. This failed the entire connection, even if IPv6's "may-fail" + property was TRUE. Instead, just fail IPv6 and allow IPv4 to proceed. If + IPv4 fails or is disabled, then other logic will fail the entire connection. + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index d99b3d7..6810afc 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -3329,8 +3329,8 @@ act_stage3_ip6_config_start (NMDevice *self, + if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { + if (!addrconf6_start (self)) { +- *reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE; +- ret = NM_ACT_STAGE_RETURN_FAILURE; ++ /* 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_DHCP) == 0) { diff --git a/rh1019021-fix-crash-ip6-routing.patch b/rh1019021-fix-crash-ip6-routing.patch new file mode 100644 index 0000000..f001a69 --- /dev/null +++ b/rh1019021-fix-crash-ip6-routing.patch @@ -0,0 +1,62 @@ +commit 19b040236ec59fe8f9730d9da6d9262921d28936 +Author: Thomas Haller +Date: Wed Oct 30 20:18:58 2013 +0100 + + core: fix segfault in nm-policy when setting default route for vpn + + nm_vpn_connection_get_ip6_internal_gateway might return NULL. In this + case, we add a device route (to gateway '::') over the vpn. + + Before, in such a case, NM crashed with SEGFAULT. + + https://bugzilla.redhat.com/show_bug.cgi?id=1019021 + + Signed-off-by: Thomas Haller + +diff --git a/src/nm-policy.c b/src/nm-policy.c +index 6d15e01..49c005c 100644 +--- a/src/nm-policy.c ++++ b/src/nm-policy.c +@@ -860,12 +860,15 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) + 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; +- struct in6_addr int_gw = *nm_vpn_connection_get_ip6_internal_gateway (vpn); ++ const struct in6_addr *int_gw = nm_vpn_connection_get_ip6_internal_gateway (vpn); + int mss = nm_ip6_config_get_mss (ip6_config); + +- if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, int_gw, 0, mss)) { ++ if (!int_gw) ++ int_gw = &in6addr_any; ++ ++ if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *int_gw, 0, mss)) { + nm_platform_ip6_route_add (parent_ifindex, *gw_addr, 128, in6addr_any, 0, parent_mss); +- if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, int_gw, 0, mss)) { ++ if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *int_gw, 0, mss)) { + nm_log_err (LOGD_IP6 | LOGD_VPN, "Failed to set default route."); + } + } +commit 886ca75ac33de252158a63074cc7cf9d0215c962 +Author: Thomas Haller +Date: Fri Nov 1 10:57:18 2013 +0100 + + core: fix crash when reading routes from VPN Ip6Config (bgo #706332) + + https://bugzilla.gnome.org/show_bug.cgi?id=706332 + + Reported-by: Nicolas Iooss + Signed-off-by: Thomas Haller + +diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c +index 6962e30..263f253 100644 +--- a/src/vpn-manager/nm-vpn-connection.c ++++ b/src/vpn-manager/nm-vpn-connection.c +@@ -1084,7 +1084,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, + * the VPN server, we want to use the NM created route instead of + * whatever the server provides. + */ +- if (IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) && route.plen == 128) ++ if (priv->ip6_external_gw && IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) && route.plen == 128) + continue; + + /* Otherwise accept the VPN-provided route */ diff --git a/rh1021112-fix-crash-never-default.patch b/rh1021112-fix-crash-never-default.patch new file mode 100644 index 0000000..58b7d29 --- /dev/null +++ b/rh1021112-fix-crash-never-default.patch @@ -0,0 +1,19 @@ +commit 0a557ac01d28340e43247eef52007a8b18bb24d8 +Author: Dan Winship +Date: Thu Oct 24 15:15:02 2013 -0400 + + core: fix crash when activating a never-default IPv4 connection + +diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c +index 81c003e..ed1728d 100644 +--- a/src/nm-ip4-config.c ++++ b/src/nm-ip4-config.c +@@ -583,7 +583,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev + /* never_default */ + if (src_priv->never_default != dst_priv->never_default) { + dst_priv->never_default = src_priv->never_default; +- has_relevant_changes = TRUE; ++ has_minor_changes = TRUE; + } + + /* default gateway */ diff --git a/rh1023571-fix-crash-ifcfg-rh-reload.patch b/rh1023571-fix-crash-ifcfg-rh-reload.patch new file mode 100644 index 0000000..60929fd --- /dev/null +++ b/rh1023571-fix-crash-ifcfg-rh-reload.patch @@ -0,0 +1,55 @@ +commit 912152cf85d29db45f706522c8e3ce13eaf13197 +Author: Jiří Klimeš +Date: Tue Oct 29 15:02:30 2013 +0100 + + ifcfg-rh: fix crash when doing managed->unmanaged transition + + Testcase: + * add 'NM_CONTROLLED=no' to /etc/sysconfig/network-scripts/ifcfg-ABC + * sudo nmcli con reload + * ... NM asserts ... + + We need to ref() 'existing' connection before nm_settings_connection_signal_remove(), + because the function unref()s ithe connection via connection_removed_cb(). + + Backtrace: + ... + #4 0x00007fbcf0ea0cba in g_assertion_message_expr (domain=domain@entry=0x0, + file=file@entry=0x7fbcf4e5805d "nm-dbus-manager.c", line=line@entry=848, + func=func@entry=0x7fbcf4e585e0 <__FUNCTION__.15088> "nm_dbus_manager_unregister_object", expr=expr@entry=0x7fbcf4e5820b "G_IS_OBJECT (object)") + at gtestutils.c:2293 + #5 0x00007fbcf4de69d9 in nm_dbus_manager_unregister_object ( + self=0x7fbcf6fdc9c0, object=0x7fbcf70235c0) at nm-dbus-manager.c:848 + #6 0x00007fbcf4dd6a23 in nm_settings_connection_signal_remove ( + self=) at settings/nm-settings-connection.c:1541 + #7 0x00007fbce6fee884 in connection_new_or_changed ( + self=self@entry=0x7fbcf7006f80, + path=path@entry=0x7fbcf70c3f80 "/etc/sysconfig/network-scripts/ifcfg-ABC", + existing=existing@entry=0x7fbcf70235c0, + out_old_path=out_old_path@entry=0x7fff2b7b8988) at plugin.c:327 + #8 0x00007fbce6feeca2 in read_connections (plugin=0x7fbcf7006f80) + at plugin.c:453 + #9 0x00007fbcf4dd8e98 in impl_settings_reload_connections ( + self=0x7fbcf6fd98c0, context=0x7fbcf70bcb30) at settings/nm-settings.c:1262 + ... + +diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c +index dbfc496..5cd24b0 100644 +--- a/src/settings/plugins/ifcfg-rh/plugin.c ++++ b/src/settings/plugins/ifcfg-rh/plugin.c +@@ -320,6 +320,7 @@ connection_new_or_changed (SCPluginIfcfg *self, + + if (new_unmanaged) { + if (!old_unmanaged) { ++ g_object_ref (existing); + /* Unexport the connection by telling the settings service it's + * been removed, and notify the settings service by signalling that + * unmanaged specs have changed. +@@ -331,6 +332,7 @@ connection_new_or_changed (SCPluginIfcfg *self, + + g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); ++ g_object_unref (existing); + } + } else { + if (old_unmanaged) { /* now managed */ diff --git a/rh1025007-fix-crash-ifcfg-rh.patch b/rh1025007-fix-crash-ifcfg-rh.patch new file mode 100644 index 0000000..bc60c77 --- /dev/null +++ b/rh1025007-fix-crash-ifcfg-rh.patch @@ -0,0 +1,35 @@ +commit 25428882839ff17c531887bfc58f6669c9708fc8 +Author: Thomas Haller +Date: Thu Oct 31 12:42:01 2013 +0100 + + ifcfg-rh: fix crash when reading connection (assert in connection_new_or_changed) + + rh #1025007 reports a crash on g_assert_no_error() in + connection_new_or_changed() of src/settings/plugins/ifcfg-rh/plugin.c. + From the back trace I am not 100% sure, what the problem was, but I + think that nm_settings_connection_replace_settings failed because of + nm_connection_update_secrets. Apparently such a situation can + happen and it should simply be accepted as valid. + + What might have happened, is that the connection used to have + secrets (maybe it had 802.1x configured?) and then it got changed, + so update_secrets() fails because the connection no longer has a + setting to which the secrets would apply. + + https://bugzilla.redhat.com/show_bug.cgi?id=1025007 + + Signed-off-by: Thomas Haller + +diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c +index 59b29ad..7dce397 100644 +--- a/src/settings/nm-settings-connection.c ++++ b/src/settings/nm-settings-connection.c +@@ -462,7 +462,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, + if (priv->agent_secrets) { + hash = nm_connection_to_hash (priv->agent_secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + if (hash) { +- success = nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, error); ++ nm_connection_update_secrets (NM_CONNECTION (self), NULL, hash, NULL); + g_hash_table_destroy (hash); + } + } From 66ccec23c5af283f4dfc02e11f4c510521214ca6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Nov 2013 20:17:59 -0600 Subject: [PATCH 08/15] core: add some debugging to help diagnose netlink errors (rh #1029213) --- NetworkManager.spec | 7 +++- rh1029213-debug-netlink-add-errors.patch | 50 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 rh1029213-debug-netlink-add-errors.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 18b1bf4..2937903 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 15%{snapshot}%{?dist} +Release: 16%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -33,6 +33,7 @@ Patch3: rh1021112-fix-crash-never-default.patch Patch4: rh1019021-fix-crash-ip6-routing.patch Patch5: rh1025007-fix-crash-ifcfg-rh.patch Patch6: rh1012151-ipv6-disable.patch +Patch7: rh1029213-debug-netlink-add-errors.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -162,6 +163,7 @@ deployments. %patch4 -p1 -b .patch4 %patch5 -p1 -b .patch5 %patch6 -p1 -b .patch6 +%patch7 -p1 -b .patch7 %build @@ -360,6 +362,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Wed Nov 13 2013 Dan Williams - 0.9.9.0-16.git20131003 +- core: add some debugging to help diagnose netlink errors (rh #1029213) + * Fri Nov 8 2013 Jiří Klimeš - 0.9.9.0-15.git20131003 - ifcfg-rh: fix crash in ifcfg-rh plugin when reloading connections (rh #1023571) - ifcfg-rh: fix crash when having connections with NEVER_DEFAULT (rh #1021112) diff --git a/rh1029213-debug-netlink-add-errors.patch b/rh1029213-debug-netlink-add-errors.patch new file mode 100644 index 0000000..3609960 --- /dev/null +++ b/rh1029213-debug-netlink-add-errors.patch @@ -0,0 +1,50 @@ +From 2086cab1273b26630840e3a0c092e8b1617e803b Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 13 Nov 2013 20:06:39 -0600 +Subject: [PATCH] platform: dump objects that fail to be added (rh #1029213) + +Attempt to figure out why the objects fail. +--- + src/platform/nm-linux-platform.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index a35b0cc..d13abbe 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -1100,27 +1100,32 @@ refresh_object (NMPlatform *platform, struct nl_object *object, gboolean removed + /* Decreases the reference count if @obj for convenience */ + static gboolean + add_object (NMPlatform *platform, struct nl_object *obj) + { + auto_nl_object struct nl_object *object = obj; + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + int nle; ++ struct nl_dump_params dp = { ++ .dp_type = NL_DUMP_DETAILS, ++ .dp_fd = stderr, ++ }; + + nle = add_kernel_object (priv->nlh, object); + + /* NLE_EXIST is considered equivalent to success to avoid race conditions. You + * never know when something sends an identical object just before + * NetworkManager. + */ + switch (nle) { + case -NLE_SUCCESS: + case -NLE_EXIST: + break; + default: + error ("Netlink error: %s", nl_geterror (nle)); ++ nl_object_dump (object, &dp); + return FALSE; + } + + return refresh_object (platform, object, FALSE, NM_PLATFORM_REASON_INTERNAL); + } + + /* Decreases the reference count if @obj for convenience */ +-- +1.8.3.1 + From c995aec4943521b5f9d9bee8df9860be85334621 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 14 Nov 2013 11:02:45 -0600 Subject: [PATCH 09/15] core: fix detection of non-mac80211 devices that do not set DEVTYPE (rh #1015598) --- NetworkManager.spec | 7 +++- rh1015598-wifi-detect.patch | 74 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 rh1015598-wifi-detect.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 2937903..87df500 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 16%{snapshot}%{?dist} +Release: 17%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -34,6 +34,7 @@ Patch4: rh1019021-fix-crash-ip6-routing.patch Patch5: rh1025007-fix-crash-ifcfg-rh.patch Patch6: rh1012151-ipv6-disable.patch Patch7: rh1029213-debug-netlink-add-errors.patch +Patch8: rh1015598-wifi-detect.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -164,6 +165,7 @@ deployments. %patch5 -p1 -b .patch5 %patch6 -p1 -b .patch6 %patch7 -p1 -b .patch7 +%patch8 -p1 -b .patch8 %build @@ -362,6 +364,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Thu Nov 14 2013 Dan Williams - 0.9.9.0-17.git20131003 +- core: fix detection of non-mac80211 devices that do not set DEVTYPE (rh #1015598) + * Wed Nov 13 2013 Dan Williams - 0.9.9.0-16.git20131003 - core: add some debugging to help diagnose netlink errors (rh #1029213) diff --git a/rh1015598-wifi-detect.patch b/rh1015598-wifi-detect.patch new file mode 100644 index 0000000..1aa7100 --- /dev/null +++ b/rh1015598-wifi-detect.patch @@ -0,0 +1,74 @@ +From 473018d8b2628ce946cc35db432ac2bc68f6f912 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 16 Oct 2013 12:29:13 -0500 +Subject: [PATCH] platform: detect non-mac80211 WiFi devices as WiFi (rh + #1015598) + +Before NMPlatform landed, the old NMManager code looked at either +DEVTYPE=wlan or asked the internal wifi utilities whether the +device was WiFi or not. This got lost when moving to NMPlatform. + +It turns out that only mac80211-based drivers set the DEVTYPE=wlan +flag in sysfs, while older WEXT, out-of-tree, and staging drivers +often do not (though they should). + +To avoid breaking recognition of these crappy drivers that used +to work, re-add the wifi utils checks. +--- + src/platform/nm-linux-platform.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index 0bea01b..82286ec 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -41,14 +41,15 @@ + #include + #include + #include + #include + + #include "nm-linux-platform.h" + #include "nm-logging.h" ++#include "wifi/wifi-utils.h" + + /* This is only included for the translation of VLAN flags */ + #include "nm-setting-vlan.h" + + #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) + #define warning(...) nm_log_warn (LOGD_PLATFORM, __VA_ARGS__) + #define error(...) nm_log_err (LOGD_PLATFORM, __VA_ARGS__) +@@ -473,26 +474,28 @@ type_to_string (NMLinkType type) + } G_STMT_END + + static NMLinkType + link_type_from_udev (NMPlatform *platform, int ifindex, int arptype, const char **out_name) + { + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + GUdevDevice *udev_device; +- const char *prop; ++ const char *prop, *name, *sysfs_path; + + udev_device = g_hash_table_lookup (priv->udev_devices, GINT_TO_POINTER (ifindex)); + if (!udev_device) + return_type (NM_LINK_TYPE_UNKNOWN, "unknown"); + + prop = g_udev_device_get_property (udev_device, "ID_NM_OLPC_MESH"); + if (prop) + return_type (NM_LINK_TYPE_OLPC_MESH, "olpc-mesh"); + + prop = g_udev_device_get_property (udev_device, "DEVTYPE"); +- if (g_strcmp0 (prop, "wlan") == 0) ++ name = g_udev_device_get_name (udev_device); ++ sysfs_path = g_udev_device_get_sysfs_path (udev_device); ++ if (g_strcmp0 (prop, "wlan") == 0 || wifi_utils_is_wifi (name, sysfs_path)) + return_type (NM_LINK_TYPE_WIFI, "wifi"); + else if (g_strcmp0 (prop, "wwan") == 0) + return_type (NM_LINK_TYPE_WWAN_ETHERNET, "wwan"); + + if (arptype == ARPHRD_ETHER) + return_type (NM_LINK_TYPE_ETHERNET, "ethernet"); + +-- +1.8.3.1 + From c7534299671ebed697da0a454691ea1870a43a8e Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 18 Nov 2013 11:31:09 -0500 Subject: [PATCH 10/15] several fixes - nmcli: add "con load" to manually load an ifcfg file - vpn: fix logging to help debug rh #1018317 - bridge: fix crash with bridge ports with empty settings (rh #1031170) --- NetworkManager.spec | 13 +- nmcli-con-load.patch | 492 ++++++++++++++++++++++++++++++ rh1018317-vpn-logging.patch | 51 ++++ rh1031170-bridge-port-crash.patch | 99 ++++++ 4 files changed, 654 insertions(+), 1 deletion(-) create mode 100644 nmcli-con-load.patch create mode 100644 rh1018317-vpn-logging.patch create mode 100644 rh1031170-bridge-port-crash.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 87df500..9e8e1c4 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 17%{snapshot}%{?dist} +Release: 18%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -35,6 +35,9 @@ Patch5: rh1025007-fix-crash-ifcfg-rh.patch Patch6: rh1012151-ipv6-disable.patch Patch7: rh1029213-debug-netlink-add-errors.patch Patch8: rh1015598-wifi-detect.patch +Patch9: nmcli-con-load.patch +Patch10: rh1018317-vpn-logging.patch +Patch11: rh1031170-bridge-port-crash.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -166,6 +169,9 @@ deployments. %patch6 -p1 -b .patch6 %patch7 -p1 -b .patch7 %patch8 -p1 -b .patch8 +%patch9 -p1 -b .nmcli-con-load +%patch10 -p1 -b .vpn-log +%patch11 -p1 -b .bridge-port %build @@ -364,6 +370,11 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Mon Nov 18 2013 Dan Winship - 0.9.9.0-18.git20131003 +- nmcli: add "con load" to manually load an ifcfg file +- vpn: fix logging to help debug rh #1018317 +- bridge: fix crash with bridge ports with empty settings (rh #1031170) + * Thu Nov 14 2013 Dan Williams - 0.9.9.0-17.git20131003 - core: fix detection of non-mac80211 devices that do not set DEVTYPE (rh #1015598) diff --git a/nmcli-con-load.patch b/nmcli-con-load.patch new file mode 100644 index 0000000..96e2f12 --- /dev/null +++ b/nmcli-con-load.patch @@ -0,0 +1,492 @@ +diff -up NetworkManager-0.9.9.0/cli/completion/nmcli.nmcli-con-load NetworkManager-0.9.9.0/cli/completion/nmcli +--- NetworkManager-0.9.9.0/cli/completion/nmcli.nmcli-con-load 2013-10-03 14:14:44.000000000 -0400 ++++ NetworkManager-0.9.9.0/cli/completion/nmcli 2013-11-18 11:02:56.187304537 -0500 +@@ -833,6 +833,12 @@ _nmcli() + _nmcli_complete_COMMAND_CONNECTION + fi + ;; ++ l|lo|loa|load) ++ if [[ ${#words[@]} -gt 2 ]]; then ++ compopt -o default ++ COMPREPLY=() ++ fi ++ ;; + esac + fi + ;; +diff -up NetworkManager-0.9.9.0/cli/src/connections.c.nmcli-con-load NetworkManager-0.9.9.0/cli/src/connections.c +--- NetworkManager-0.9.9.0/cli/src/connections.c.nmcli-con-load 2013-10-03 15:00:47.000000000 -0400 ++++ NetworkManager-0.9.9.0/cli/src/connections.c 2013-11-18 11:02:56.188304537 -0500 +@@ -222,7 +222,8 @@ usage (void) + " modify [ id | uuid | path ] . \n\n" + " edit [ id | uuid | path ] | [type ] [con-name ]\n\n" + " delete [ id | uuid | path ] \n\n" +- " reload\n\n\n" ++ " reload\n\n" ++ " load [ ... ]\n\n\n" + )); + } + +@@ -308,6 +309,7 @@ static const char *real_con_commands[] = + "edit", + "delete", + "reload", ++ "load", + NULL + }; + +@@ -7006,6 +7008,50 @@ do_connection_reload (NmCli *nmc, int ar + return nmc->return_value; + } + ++static NMCResultCode ++do_connection_load (NmCli *nmc, int argc, char **argv) ++{ ++ GError *error = NULL; ++ char **filenames, **failures = NULL; ++ int i; ++ ++ nmc->return_value = NMC_RESULT_SUCCESS; ++ nmc->should_wait = FALSE; ++ ++ if (!nm_client_get_manager_running (nmc->client)) { ++ g_string_printf (nmc->return_text, _("Error: NetworkManager is not running.")); ++ nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; ++ return nmc->return_value; ++ } ++ ++ if (argc == 0) { ++ g_string_printf (nmc->return_text, _("Error: No connection specified.")); ++ nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; ++ return nmc->return_value; ++ } ++ ++ filenames = g_new (char *, argc + 1); ++ for (i = 0; i < argc; i++) ++ filenames[i] = argv[i]; ++ filenames[i] = NULL; ++ ++ nm_remote_settings_load_connections (nmc->system_settings, filenames, &failures, &error); ++ g_free (filenames); ++ if (error) { ++ g_string_printf (nmc->return_text, _("Error: %s."), error->message); ++ nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; ++ g_error_free (error); ++ } ++ ++ if (failures) { ++ for (i = 0; failures[i]; i++) ++ fprintf (stderr, _("Could not load file '%s'\n"), failures[i]); ++ g_strfreev (failures); ++ } ++ ++ return nmc->return_value; ++} ++ + + typedef struct { + NmCli *nmc; +@@ -7087,6 +7133,9 @@ parse_cmd (NmCli *nmc, int argc, char ** + else if (matches(*argv, "reload") == 0) { + nmc->return_value = do_connection_reload (nmc, argc-1, argv+1); + } ++ else if (matches(*argv, "load") == 0) { ++ nmc->return_value = do_connection_load (nmc, argc-1, argv+1); ++ } + else if (matches (*argv, "modify") == 0) { + nmc->return_value = do_connection_modify (nmc, argc-1, argv+1); + } +diff -up NetworkManager-0.9.9.0/introspection/nm-settings.xml.nmcli-con-load NetworkManager-0.9.9.0/introspection/nm-settings.xml +--- NetworkManager-0.9.9.0/introspection/nm-settings.xml.nmcli-con-load 2013-09-27 23:40:17.000000000 -0400 ++++ NetworkManager-0.9.9.0/introspection/nm-settings.xml 2013-11-18 11:02:56.188304537 -0500 +@@ -82,6 +82,40 @@ + + + ++ ++ ++ Loads or reloads the indicated connections from disk. You ++ should call this after making changes directly to an on-disk ++ connection file to make sure that NetworkManager sees the ++ changes. (If "monitor-connection-files" in NetworkManager.conf ++ is "true", then this will have no real effect, but is ++ harmless.) As with AddConnection(), this operation does not ++ necessarily start the network connection. ++ ++ ++ ++ ++ ++ Array of paths to on-disk connection profiles in directories ++ monitored by NetworkManager. ++ ++ ++ ++ ++ Success or failure of the operation as a whole. True if ++ NetworkManager at least tried to load the indicated ++ connections, even if it did not succeed. False if an error ++ occurred before trying to load the connections (eg, ++ permission denied). ++ ++ ++ ++ ++ Paths of connection files that could not be loaded. ++ ++ ++ ++ + + + Tells NetworkManager to reload all connection files from disk, +diff -up NetworkManager-0.9.9.0/libnm-glib/libnm-glib.ver.nmcli-con-load NetworkManager-0.9.9.0/libnm-glib/libnm-glib.ver +--- NetworkManager-0.9.9.0/libnm-glib/libnm-glib.ver.nmcli-con-load 2013-10-01 14:43:57.000000000 -0400 ++++ NetworkManager-0.9.9.0/libnm-glib/libnm-glib.ver 2013-11-18 11:02:56.188304537 -0500 +@@ -243,6 +243,7 @@ global: + nm_remote_settings_get_connection_by_uuid; + nm_remote_settings_get_type; + nm_remote_settings_list_connections; ++ nm_remote_settings_load_connections; + nm_remote_settings_new; + nm_remote_settings_new_async; + nm_remote_settings_new_finish; +diff -up NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.c.nmcli-con-load NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.c +--- NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.c.nmcli-con-load 2013-09-27 23:40:17.000000000 -0400 ++++ NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.c 2013-11-18 11:02:56.188304537 -0500 +@@ -630,6 +630,72 @@ nm_remote_settings_add_connection_unsave + } + + /** ++ * nm_remote_settings_load_connections: ++ * @settings: the %NMRemoteSettings ++ * @filenames: %NULL-terminated array of filenames to load ++ * @failures: (out) (transfer full): on return, a %NULL-terminated array of ++ * filenames that failed to load ++ * @error: return location for #GError ++ * ++ * Requests that the remote settings service load or reload the given files, ++ * adding or updating the connections described within. ++ * ++ * The changes to the indicated files will not yet be reflected in ++ * @settings's connections array when the function returns. ++ * ++ * If all of the indicated files were successfully loaded, the ++ * function will return %TRUE, and @failures will be set to %NULL. If ++ * NetworkManager tried to load the files, but some (or all) failed, ++ * then @failures will be set to a %NULL-terminated array of the ++ * filenames that failed to load. ++ ++ * Returns: %TRUE if NetworkManager at least tried to load @filenames, ++ * %FALSE if an error occurred (eg, permission denied). ++ * ++ * Since: 0.9.10 ++ **/ ++gboolean ++nm_remote_settings_load_connections (NMRemoteSettings *settings, ++ char **filenames, ++ char ***failures, ++ GError **error) ++{ ++ NMRemoteSettingsPrivate *priv; ++ char **my_failures = NULL; ++ gboolean ret = FALSE; ++ ++ g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); ++ g_return_val_if_fail (filenames != NULL, NULL); ++ ++ priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); ++ ++ _nm_remote_settings_ensure_inited (settings); ++ ++ if (!priv->service_running) { ++ g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, ++ NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, ++ "NetworkManager is not running."); ++ return FALSE; ++ } ++ ++ dbus_g_proxy_call (priv->proxy, "LoadConnections", error, ++ G_TYPE_STRV, filenames, ++ G_TYPE_INVALID, ++ G_TYPE_BOOLEAN, &ret, ++ G_TYPE_STRV, &my_failures, ++ G_TYPE_INVALID); ++ ++ if (failures) { ++ if (my_failures && !*my_failures) ++ g_clear_pointer (&my_failures, g_free); ++ *failures = my_failures; ++ } else ++ g_strfreev (my_failures); ++ ++ return ret; ++} ++ ++/** + * nm_remote_settings_reload_connections: + * @settings: the #NMRemoteSettings + * @error: return location for #GError +diff -up NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.h.nmcli-con-load NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.h +--- NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.h.nmcli-con-load 2013-09-27 23:40:17.000000000 -0400 ++++ NetworkManager-0.9.9.0/libnm-glib/nm-remote-settings.h 2013-11-18 11:02:56.188304537 -0500 +@@ -79,6 +79,11 @@ typedef void (*NMRemoteSettingsAddConnec + GError *error, + gpointer user_data); + ++typedef void (*NMRemoteSettingsLoadConnectionsFunc) (NMRemoteSettings *settings, ++ char **failures, ++ GError *error, ++ gpointer user_data); ++ + typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings, + GError *error, + gpointer user_data); +@@ -135,6 +140,11 @@ gboolean nm_remote_settings_add_connecti + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data); + ++gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings, ++ char **filenames, ++ char ***failures, ++ GError **error); ++ + gboolean nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GError **error); + +diff -up NetworkManager-0.9.9.0/src/settings/nm-settings.c.nmcli-con-load NetworkManager-0.9.9.0/src/settings/nm-settings.c +--- NetworkManager-0.9.9.0/src/settings/nm-settings.c.nmcli-con-load 2013-10-01 14:43:57.000000000 -0400 ++++ NetworkManager-0.9.9.0/src/settings/nm-settings.c 2013-11-18 11:10:31.800329234 -0500 +@@ -104,6 +104,10 @@ static void impl_settings_add_connection + GHashTable *settings, + DBusGMethodInvocation *context); + ++static void impl_settings_load_connections (NMSettings *self, ++ char **filenames, ++ DBusGMethodInvocation *context); ++ + static void impl_settings_reload_connections (NMSettings *self, + DBusGMethodInvocation *context); + +@@ -1226,33 +1230,78 @@ impl_settings_add_connection_unsaved (NM + impl_settings_add_connection_helper (self, settings, FALSE, context); + } + +-static void +-impl_settings_reload_connections (NMSettings *self, +- DBusGMethodInvocation *context) ++static gboolean ++ensure_root (NMDBusManager *dbus_mgr, ++ DBusGMethodInvocation *context) + { +- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); +- GSList *iter; + gulong caller_uid; + GError *error = NULL; + +- if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr, context, NULL, &caller_uid)) { ++ if (!nm_dbus_manager_get_caller_info (dbus_mgr, context, NULL, &caller_uid)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, +- NM_SETTINGS_ERROR_PERMISSION_DENIED, +- "Unable to determine request UID."); ++ NM_SETTINGS_ERROR_PERMISSION_DENIED, ++ "Unable to determine request UID."); + dbus_g_method_return_error (context, error); + g_error_free (error); +- return; ++ return FALSE; + } + if (caller_uid != 0) { +- nm_log_warn (LOGD_SETTINGS, "ReloadConnections: permission denied to %lu", caller_uid); + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Permission denied"); + dbus_g_method_return_error (context, error); + g_error_free (error); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++static void ++impl_settings_load_connections (NMSettings *self, ++ char **filenames, ++ DBusGMethodInvocation *context) ++{ ++ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); ++ GPtrArray *failures; ++ GSList *iter; ++ int i; ++ ++ if (!ensure_root (priv->dbus_mgr, context)) + return; ++ ++ failures = g_ptr_array_new (); ++ ++ for (i = 0; filenames[i]; i++) { ++ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { ++ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); ++ ++ if (nm_system_config_interface_load_connection (plugin, filenames[i])) ++ break; ++ } ++ ++ if (!iter) { ++ if (!g_path_is_absolute (filenames[i])) ++ nm_log_warn (LOGD_SETTINGS, "Connection filename '%s' is not an absolute path", filenames[i]); ++ g_ptr_array_add (failures, (char *) filenames[i]); ++ } + } + ++ g_ptr_array_add (failures, NULL); ++ dbus_g_method_return (context, failures->len == 1, failures->pdata); ++ g_ptr_array_unref (failures); ++} ++ ++static void ++impl_settings_reload_connections (NMSettings *self, ++ DBusGMethodInvocation *context) ++{ ++ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); ++ GSList *iter; ++ ++ if (!ensure_root (priv->dbus_mgr, context)) ++ return; ++ + if (!priv->connections_loaded) { + load_connections (self); + } else { +diff -up NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.c.nmcli-con-load NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.c +--- NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.c.nmcli-con-load 2013-09-27 23:40:17.000000000 -0400 ++++ NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.c 2013-11-18 11:02:56.189304537 -0500 +@@ -137,6 +137,17 @@ nm_system_config_interface_get_connectio + return NULL; + } + ++gboolean ++nm_system_config_interface_load_connection (NMSystemConfigInterface *config, ++ const char *filename) ++{ ++ g_return_val_if_fail (config != NULL, NULL); ++ ++ if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection) ++ return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->load_connection (config, filename); ++ return FALSE; ++} ++ + void + nm_system_config_interface_reload_connections (NMSystemConfigInterface *config) + { +diff -up NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.h.nmcli-con-load NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.h +--- NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.h.nmcli-con-load 2013-09-27 23:40:17.000000000 -0400 ++++ NetworkManager-0.9.9.0/src/settings/nm-system-config-interface.h 2013-11-18 11:02:56.189304537 -0500 +@@ -89,6 +89,12 @@ struct _NMSystemConfigInterface { + */ + GSList * (*get_connections) (NMSystemConfigInterface *config); + ++ /* Requests that the plugin load/reload a single connection, if it ++ * recognizes the filename. Returns success or failure. ++ */ ++ gboolean (*load_connection) (NMSystemConfigInterface *config, ++ const char *filename); ++ + /* Requests that the plugin reload all connection files from disk, + * and emit signals reflecting new, changed, and removed connections. + */ +@@ -142,6 +148,8 @@ void nm_system_config_interface_init (NM + + GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *config); + ++gboolean nm_system_config_interface_load_connection (NMSystemConfigInterface *config, ++ const char *filename); + void nm_system_config_interface_reload_connections (NMSystemConfigInterface *config); + + GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config); +diff -up NetworkManager-0.9.9.0/src/settings/plugins/ifcfg-rh/plugin.c.nmcli-con-load NetworkManager-0.9.9.0/src/settings/plugins/ifcfg-rh/plugin.c +--- NetworkManager-0.9.9.0/src/settings/plugins/ifcfg-rh/plugin.c.nmcli-con-load 2013-11-18 11:02:56.177304536 -0500 ++++ NetworkManager-0.9.9.0/src/settings/plugins/ifcfg-rh/plugin.c 2013-11-18 11:05:18.187312234 -0500 +@@ -500,6 +500,30 @@ get_connections (NMSystemConfigInterface + return list; + } + ++static gboolean ++load_connection (NMSystemConfigInterface *config, ++ const char *filename) ++{ ++ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config); ++ NMIfcfgConnection *connection; ++ int dir_len = strlen (IFCFG_DIR); ++ ++ if ( strncmp (filename, IFCFG_DIR, dir_len) != 0 ++ || filename[dir_len] != '/' ++ || strchr (filename + dir_len + 1, '/') != NULL) ++ return FALSE; ++ ++ if (utils_should_ignore_file (filename + dir_len + 1, TRUE)) ++ return FALSE; ++ ++ connection = find_by_path (plugin, filename); ++ connection_new_or_changed (plugin, filename, connection, NULL); ++ if (!connection) ++ connection = find_by_path (plugin, filename); ++ ++ return (connection != NULL); ++} ++ + static void + reload_connections (NMSystemConfigInterface *config) + { +@@ -939,6 +963,7 @@ system_config_interface_init (NMSystemCo + /* interface implementation */ + system_config_interface_class->get_connections = get_connections; + system_config_interface_class->add_connection = add_connection; ++ system_config_interface_class->load_connection = load_connection; + system_config_interface_class->reload_connections = reload_connections; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; + system_config_interface_class->init = init; +diff -up NetworkManager-0.9.9.0/src/settings/plugins/keyfile/plugin.c.nmcli-con-load NetworkManager-0.9.9.0/src/settings/plugins/keyfile/plugin.c +--- NetworkManager-0.9.9.0/src/settings/plugins/keyfile/plugin.c.nmcli-con-load 2013-10-01 14:43:58.000000000 -0400 ++++ NetworkManager-0.9.9.0/src/settings/plugins/keyfile/plugin.c 2013-11-18 11:02:56.189304537 -0500 +@@ -403,6 +403,33 @@ get_connections (NMSystemConfigInterface + return list; + } + ++static gboolean ++load_connection (NMSystemConfigInterface *config, ++ const char *filename) ++{ ++ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); ++ NMKeyfileConnection *connection; ++ int dir_len = strlen (KEYFILE_DIR); ++ ++ if ( strncmp (filename, KEYFILE_DIR, dir_len) != 0 ++ || filename[dir_len] != '/' ++ || strchr (filename + dir_len + 1, '/') != NULL) ++ return FALSE; ++ ++ if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1)) ++ return FALSE; ++ ++ connection = find_by_path (self, filename); ++ if (connection) ++ update_connection (self, connection, filename); ++ else { ++ new_connection (self, filename, NULL); ++ connection = find_by_path (self, filename); ++ } ++ ++ return (connection != NULL); ++} ++ + static void + reload_connections (NMSystemConfigInterface *config) + { +@@ -701,6 +728,7 @@ system_config_interface_init (NMSystemCo + { + /* interface implementation */ + system_config_interface_class->get_connections = get_connections; ++ system_config_interface_class->load_connection = load_connection; + system_config_interface_class->reload_connections = reload_connections; + system_config_interface_class->add_connection = add_connection; + system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; diff --git a/rh1018317-vpn-logging.patch b/rh1018317-vpn-logging.patch new file mode 100644 index 0000000..685bdd3 --- /dev/null +++ b/rh1018317-vpn-logging.patch @@ -0,0 +1,51 @@ +From ec1cabde2872337a98b1f5fb8e1e9b8219548010 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Wed, 30 Oct 2013 22:39:32 +0100 +Subject: [PATCH] core: fix error in print_vpn_config to print the route + correctly + +ip_address_to_string returns a static buffer, need to make a copy +in this case. + +Signed-off-by: Thomas Haller +--- + src/vpn-manager/nm-vpn-connection.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c +index a3074aa..7d3582a 100644 +--- a/src/vpn-manager/nm-vpn-connection.c ++++ b/src/vpn-manager/nm-vpn-connection.c +@@ -576,11 +576,13 @@ print_vpn_config (NMVPNConnection *connection) + num = nm_ip4_config_get_num_routes (priv->ip4_config); + for (i = 0; i < num; i++) { + const NMPlatformIP4Route *route = nm_ip4_config_get_route (priv->ip4_config, i); ++ char *s = g_strdup (ip_address_to_string (route->gateway)); + + nm_log_info (LOGD_VPN, " Static Route: %s/%d Next Hop: %s", + ip_address_to_string (route->network), + route->plen, +- ip_address_to_string (route->gateway)); ++ s); ++ g_free (s); + } + + nm_log_info (LOGD_VPN, " Forbid Default Route: %s", +@@ -615,11 +617,13 @@ print_vpn_config (NMVPNConnection *connection) + num = nm_ip6_config_get_num_routes (priv->ip6_config); + for (i = 0; i < num; i++) { + const NMPlatformIP6Route *route = nm_ip6_config_get_route (priv->ip6_config, i); ++ char *s = g_strdup (ip6_address_to_string (&route->gateway)); + + nm_log_info (LOGD_VPN, " Static Route: %s/%d Next Hop: %s", + ip6_address_to_string (&route->network), + route->plen, +- ip6_address_to_string (&route->gateway)); ++ s); ++ g_free (s); + } + + nm_log_info (LOGD_VPN, " Forbid Default Route: %s", +-- +1.8.4.2 + diff --git a/rh1031170-bridge-port-crash.patch b/rh1031170-bridge-port-crash.patch new file mode 100644 index 0000000..01f980d --- /dev/null +++ b/rh1031170-bridge-port-crash.patch @@ -0,0 +1,99 @@ +From 8a046bedbbf8218737d7471f949a541b35579539 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Fri, 11 Oct 2013 18:25:20 +0200 +Subject: [PATCH] core: fix crash for bridge-slave with missing + NMSettingBridgePort setting + +Signed-off-by: Thomas Haller +--- + src/devices/nm-device-bridge.c | 29 ++++++++++++++++++----------- + 1 file changed, 18 insertions(+), 11 deletions(-) + +diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c +index 69e976c..2018e93 100644 +--- a/src/devices/nm-device-bridge.c ++++ b/src/devices/nm-device-bridge.c +@@ -203,7 +203,7 @@ static const Option slave_options[] = { + }; + + static void +-commit_option (NMDevice *device, GObject *setting, const Option *option, gboolean slave) ++commit_option (NMDevice *device, NMSetting *setting, const Option *option, gboolean slave) + { + int ifindex = nm_device_get_ifindex (device); + GParamSpec *pspec; +@@ -211,12 +211,14 @@ commit_option (NMDevice *device, GObject *setting, const Option *option, gboolea + guint32 uval = 0; + gs_free char *value = NULL; + ++ g_assert (setting); ++ + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), option->name); + g_assert (pspec); + + /* Get the property's value */ + g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec)); +- g_object_get_property (setting, option->name, &val); ++ g_object_get_property ((GObject *) setting, option->name, &val); + if (G_VALUE_HOLDS_BOOLEAN (&val)) + uval = g_value_get_boolean (&val) ? 1 : 0; + else if (G_VALUE_HOLDS_UINT (&val)) { +@@ -251,25 +253,30 @@ commit_option (NMDevice *device, GObject *setting, const Option *option, gboolea + } + + static void +-commit_master_options (NMDevice *device, GObject *setting) ++commit_master_options (NMDevice *device, NMSettingBridge *setting) + { + const Option *option; +- +- g_assert (setting); ++ NMSetting *s = NM_SETTING (setting); + + for (option = master_options; option->name; option++) +- commit_option (device, setting, option, FALSE); ++ commit_option (device, s, option, FALSE); + } + + static void +-commit_slave_options (NMDevice *device, GObject *setting) ++commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) + { + const Option *option; ++ NMSetting *s, *s_clear = NULL; + +- g_assert (setting); ++ if (setting) ++ s = NM_SETTING (setting); ++ else ++ s = s_clear = nm_setting_bridge_port_new (); + + for (option = slave_options; option->name; option++) +- commit_option (device, setting, option, TRUE); ++ commit_option (device, s, option, TRUE); ++ ++ g_clear_object (&s_clear); + } + + static NMActStageReturn +@@ -284,7 +291,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) + return ret; + +- commit_master_options (device, (GObject *) nm_connection_get_setting_bridge (connection)); ++ commit_master_options (device, nm_connection_get_setting_bridge (connection)); + + return NM_ACT_STAGE_RETURN_SUCCESS; + } +@@ -295,7 +302,7 @@ enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection) + if (!nm_platform_link_enslave (nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave))) + return FALSE; + +- commit_slave_options (slave, (GObject *) nm_connection_get_setting_bridge_port (connection)); ++ 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), +-- +1.8.4.2 + From b75568ba24371051ae5bc30c87d47266637a6b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 20 Nov 2013 14:02:51 +0100 Subject: [PATCH 11/15] cherry-picked several fixes (for crashes) - dispatcher: fix crash on exit while logging from signal handler (rh #1017884) - core: workaround crash when connecting to wifi (rh #1025371) - ethernet: don't crash if device doesn't have a MAC address (rh #1029053) - libnm-glib: fix crash by taking additional ref in result_cb() (rh #1030403) - ifcfg-rh: fix ignoring updates that don't change anything --- NetworkManager.spec | 19 +++- fix-ifcfg-rh-con-update.patch | 53 +++++++++++ rh1017884-dispatcher-crash-on-exit.patch | 88 ++++++++++++++++++ rh1025371-wifi-potential-crash.patch | 92 +++++++++++++++++++ rh1029053-fix-crash-device-no-MAC.patch | 73 +++++++++++++++ ...30403-editor-crash-remote-connection.patch | 45 +++++++++ 6 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 fix-ifcfg-rh-con-update.patch create mode 100644 rh1017884-dispatcher-crash-on-exit.patch create mode 100644 rh1025371-wifi-potential-crash.patch create mode 100644 rh1029053-fix-crash-device-no-MAC.patch create mode 100644 rh1030403-editor-crash-remote-connection.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 9e8e1c4..0484c57 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 18%{snapshot}%{?dist} +Release: 19%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -38,6 +38,11 @@ Patch8: rh1015598-wifi-detect.patch Patch9: nmcli-con-load.patch Patch10: rh1018317-vpn-logging.patch Patch11: rh1031170-bridge-port-crash.patch +Patch12: rh1017884-dispatcher-crash-on-exit.patch +Patch13: rh1025371-wifi-potential-crash.patch +Patch14: rh1029053-fix-crash-device-no-MAC.patch +Patch15: rh1030403-editor-crash-remote-connection.patch +Patch16: fix-ifcfg-rh-con-update.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -172,6 +177,11 @@ deployments. %patch9 -p1 -b .nmcli-con-load %patch10 -p1 -b .vpn-log %patch11 -p1 -b .bridge-port +%patch12 -p1 -b .dispatcher +%patch13 -p1 -b .wifi-crash +%patch14 -p1 -b .device-no-MAC +%patch15 -p1 -b .libnm-glib-editor +%patch16 -p1 -b .ifcfg-rh-update %build @@ -370,6 +380,13 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Wed Nov 20 2013 Jiří Klimeš - 0.9.9.0-19.git20131003 +- dispatcher: fix crash on exit while logging from signal handler (rh #1017884) +- core: workaround crash when connecting to wifi (rh #1025371) +- ethernet: don't crash if device doesn't have a MAC address (rh #1029053) +- libnm-glib: fix crash by taking additional ref in result_cb() (rh #1030403) +- ifcfg-rh: fix ignoring updates that don't change anything + * Mon Nov 18 2013 Dan Winship - 0.9.9.0-18.git20131003 - nmcli: add "con load" to manually load an ifcfg file - vpn: fix logging to help debug rh #1018317 diff --git a/fix-ifcfg-rh-con-update.patch b/fix-ifcfg-rh-con-update.patch new file mode 100644 index 0000000..1c13d78 --- /dev/null +++ b/fix-ifcfg-rh-con-update.patch @@ -0,0 +1,53 @@ +From 87041545b40fd0c0cfae16a8e605552b7715dc15 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Fri, 4 Oct 2013 23:38:31 -0500 +Subject: [PATCH] ifcfg-rh: fix ignoring updates that don't change anything +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +connection_from_file() requires the 'error' parameter. Not passing a +valid 'error' parameter causes the function to fail and return NULL, +which mean that commit_changes() would always re-write the connection +instead of ignoring commits where nothing has actually changed. + +connection_from_file() no longer requires the unmanaged, keyfile, +or routefile parameters, so remove them. + +Signed-off-by: Jiří Klimeš +--- + src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +index 3788149..d3b93c9 100644 +--- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c ++++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +@@ -246,7 +246,6 @@ commit_changes (NMSettingsConnection *connection, + NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); + GError *error = NULL; + NMConnection *reread; +- char *unmanaged = NULL, *keyfile = NULL, *routefile = NULL, *route6file = NULL; + gboolean same = FALSE, success = FALSE; + char *ifcfg_path = NULL; + +@@ -256,13 +255,9 @@ commit_changes (NMSettingsConnection *connection, + */ + if (priv->path) { + reread = connection_from_file (priv->path, NULL, NULL, NULL, +- &unmanaged, &keyfile, &routefile, &route6file, +- NULL, NULL); +- g_free (unmanaged); +- g_free (keyfile); +- g_free (routefile); +- g_free (route6file); +- ++ NULL, NULL, NULL, NULL, ++ &error, NULL); ++ g_clear_error (&error); + if (reread) { + same = nm_connection_compare (NM_CONNECTION (connection), + reread, +-- +1.7.11.7 + diff --git a/rh1017884-dispatcher-crash-on-exit.patch b/rh1017884-dispatcher-crash-on-exit.patch new file mode 100644 index 0000000..436df2f --- /dev/null +++ b/rh1017884-dispatcher-crash-on-exit.patch @@ -0,0 +1,88 @@ +From 073cc01f52f8b2b6d5b20c63814dc1ed00699028 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 18 Nov 2013 23:37:58 +0100 +Subject: [PATCH] dispatcher: fix crash while logging from signal handler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bug rh#1017884 describes a crash, where dbus_init() failed, which causes +a g_warning(). While writing the warning, a SIGTERM hit, and the +signal_handler() tries to call again g_message(). + +The logging functions of glib are not reentrant and call abort() when +invoked recursivly. The solution, is to use g_unix_signal_add, which +will dispatch the handler on the mainloop asynchronously. + +This bug is not that serious, because the dispatcher was about to +terminate anyway. However, it gets registered as a crash by the system +(ABRT). + +https://bugzilla.redhat.com/show_bug.cgi?id=1017884 + +Signed-off-by: Thomas Haller +Signed-off-by: Jiří Klimeš +--- + callouts/nm-dispatcher-action.c | 30 ++++++++++-------------------- + 1 file changed, 10 insertions(+), 20 deletions(-) + +diff --git a/callouts/nm-dispatcher-action.c b/callouts/nm-dispatcher-action.c +index 397f2ba..f48ff0a 100644 +--- a/callouts/nm-dispatcher-action.c ++++ b/callouts/nm-dispatcher-action.c +@@ -31,6 +31,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -597,27 +598,15 @@ logging_shutdown (void) + closelog (); + } + +-static void +-signal_handler (int signo) ++static gboolean ++signal_handler (gpointer user_data) + { +- if (signo == SIGINT || signo == SIGTERM) { +- g_message ("Caught signal %d, shutting down...", signo); +- g_main_loop_quit (loop); +- } +-} ++ int signo = GPOINTER_TO_INT (user_data); + +-static void +-setup_signals (void) +-{ +- struct sigaction action; +- sigset_t mask; +- +- sigemptyset (&mask); +- action.sa_handler = signal_handler; +- action.sa_mask = mask; +- action.sa_flags = 0; +- sigaction (SIGTERM, &action, NULL); +- sigaction (SIGINT, &action, NULL); ++ g_message ("Caught signal %d, shutting down...", signo); ++ g_main_loop_quit (loop); ++ ++ return G_SOURCE_REMOVE; + } + + int +@@ -648,7 +637,8 @@ main (int argc, char **argv) + g_option_context_free (opt_ctx); + + g_type_init (); +- setup_signals (); ++ g_unix_signal_add (SIGTERM, signal_handler, GINT_TO_POINTER (SIGTERM)); ++ g_unix_signal_add (SIGINT, signal_handler, GINT_TO_POINTER (SIGINT)); + + if (!debug) + logging_setup (); +-- +1.7.11.7 + diff --git a/rh1025371-wifi-potential-crash.patch b/rh1025371-wifi-potential-crash.patch new file mode 100644 index 0000000..d1597c7 --- /dev/null +++ b/rh1025371-wifi-potential-crash.patch @@ -0,0 +1,92 @@ +From 788eed99de51cd35adeb6585379b5e920c79b3f3 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Fri, 1 Nov 2013 10:32:27 +0100 +Subject: [PATCH] core: workaround crash when connecting to wifi (rh #1025371) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +rh #1025371 reports a crash in handle_ip_config_timeout() because +nm_device_wifi_get_activation_ap() did not return any access point. + +The handling of the AP in nm-device-wifi.c should be reworked and soon +will be fixed. For now, play it safe, and try to cope with any cases +where nm_device_wifi_get_activation_ap() might return NULL. + +Later, this patch should be reverted and handling of the AP properly +cleaned up. + +https://bugzilla.redhat.com/show_bug.cgi?id=1025371 + +Signed-off-by: Thomas Haller +Signed-off-by: Jiří Klimeš +--- + src/devices/nm-device-wifi.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/devices/nm-device-wifi.c b/src/devices/nm-device-wifi.c +index 855c1e7..6c19d62 100644 +--- a/src/devices/nm-device-wifi.c ++++ b/src/devices/nm-device-wifi.c +@@ -2313,7 +2313,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, + */ + if (devstate == NM_DEVICE_STATE_CONFIG) { + NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self); +- const GByteArray *ssid = nm_ap_get_ssid (ap); ++ const GByteArray *ssid = ap ? nm_ap_get_ssid (ap) : NULL; + + nm_log_info (LOGD_DEVICE | LOGD_WIFI, + "Activation (%s/wireless) Stage 2 of 5 (Device Configure) " +@@ -2593,9 +2593,8 @@ supplicant_connection_timeout_cb (gpointer user_data) + + g_assert (priv->mode == NM_802_11_MODE_INFRA); + ap = nm_device_wifi_get_activation_ap (self); +- g_assert (ap); + +- if (priv->ssid_found && is_encrypted (ap, connection)) { ++ if (priv->ssid_found && ap && is_encrypted (ap, connection)) { + guint64 timestamp = 0; + gboolean new_secrets = TRUE; + +@@ -2944,7 +2943,11 @@ act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) + g_assert (req); + + ap = nm_device_wifi_get_activation_ap (self); +- g_assert (ap); ++ if (!ap) { ++ nm_log_warn (LOGD_DEVICE | LOGD_WIFI, "act_stage2_config failed due to unexpected missing activation_ap. Abort"); ++ *reason = NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT; ++ goto out; ++ } + + connection = nm_act_request_get_connection (req); + g_assert (connection); +@@ -3102,7 +3105,6 @@ handle_ip_config_timeout (NMDeviceWifi *self, + } + + ap = nm_device_wifi_get_activation_ap (self); +- g_assert (ap); + + /* If IP configuration times out and it's a static WEP connection, that + * usually means the WEP key is wrong. WEP's Open System auth mode has +@@ -3111,7 +3113,7 @@ handle_ip_config_timeout (NMDeviceWifi *self, + * types (open, WPA, 802.1x, etc) if the secrets/certs were wrong the + * connection would have failed before IP configuration. + */ +- if (is_static_wep (ap, connection) && (may_fail == FALSE)) { ++ if (ap && is_static_wep (ap, connection) && (may_fail == FALSE)) { + /* Activation failed, we must have bad encryption key */ + nm_log_warn (LOGD_DEVICE | LOGD_WIFI, + "Activation (%s/wireless): could not get IP configuration for " +@@ -3203,7 +3205,7 @@ activation_success_handler (NMDevice *dev) + /* If the AP isn't fake, it was found in the scan list and all its + * details are known. + */ +- if (!nm_ap_get_fake (ap)) ++ if (!ap || !nm_ap_get_fake (ap)) + goto done; + + /* If the activate AP was fake, it probably won't have a BSSID at all. +-- +1.7.11.7 + diff --git a/rh1029053-fix-crash-device-no-MAC.patch b/rh1029053-fix-crash-device-no-MAC.patch new file mode 100644 index 0000000..fdac258 --- /dev/null +++ b/rh1029053-fix-crash-device-no-MAC.patch @@ -0,0 +1,73 @@ +From 696f655d7c7b605d0344aeb6ba4ff643cd46a5b4 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Mon, 11 Nov 2013 15:43:13 -0600 +Subject: [PATCH] ethernet: don't crash if device doesn't have a MAC address + (rh #1029053) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Like IBM s390 CTC devices, which aren't really ethernet but for +historical reasons we treat them as such. + +Signed-off-by: Jiří Klimeš + +Updated to apply for Fedora 20 snapshot. + +--- + src/devices/nm-device-ethernet.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c +index 7b1c248..c0b7861 100644 +--- a/src/devices/nm-device-ethernet.c ++++ b/src/devices/nm-device-ethernet.c +@@ -310,6 +310,7 @@ update_permanent_hw_address (NMDevice *dev) + struct ifreq req; + struct ethtool_perm_addr *epaddr = NULL; + int fd, ret; ++ const guint8 *mac; + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { +@@ -332,7 +333,11 @@ update_permanent_hw_address (NMDevice *dev) + nm_log_dbg (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)", + nm_device_get_iface (dev), errno); + /* Fall back to current address */ +- memcpy (epaddr->data, nm_device_get_hw_address (dev, NULL), ETH_ALEN); ++ mac = nm_device_get_hw_address (dev, NULL); ++ if (mac) ++ memcpy (epaddr->data, mac, ETH_ALEN); ++ else ++ memset (epaddr->data, 0, ETH_ALEN); + } + + if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) { +@@ -350,11 +355,14 @@ 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. + */ +- memcpy (priv->initial_hw_addr, nm_device_get_hw_address (dev, NULL), ETH_ALEN); ++ 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", +@@ -1219,7 +1219,7 @@ update_connection (NMDevice *device, NMConnection *connection) + { + NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); + guint maclen; +- gconstpointer mac = nm_device_get_hw_address (device, &maclen); ++ const guint8 *mac = nm_device_get_hw_address (device, &maclen); + + if (!s_wired) { + s_wired = (NMSettingWired *) nm_setting_wired_new (); +-- +1.7.11.7 + diff --git a/rh1030403-editor-crash-remote-connection.patch b/rh1030403-editor-crash-remote-connection.patch new file mode 100644 index 0000000..5fcc7f7 --- /dev/null +++ b/rh1030403-editor-crash-remote-connection.patch @@ -0,0 +1,45 @@ +From fbcabeb7f72b710a790ca8617f7406a1ba7cf5be Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 18 Nov 2013 22:20:05 +0100 +Subject: [PATCH] libnm-glib: fix crash by taking additional ref in + nm-remote-connection/result_cb +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +result_cb invokes a function pointer provided by the user. Nothing prevents +the user from destroying the NMRemoteConnection in the callback, which leads +to a crash. Take an additional ref of NMRemoteConnection to keep it +alive. + +This probably caused a crash for nm-applet: +https://bugzilla.redhat.com/show_bug.cgi?id=1030403 + +Signed-off-by: Thomas Haller +Signed-off-by: Jiří Klimeš +--- + libnm-glib/nm-remote-connection.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c +index a03a44b..73a2cc8 100644 +--- a/libnm-glib/nm-remote-connection.c ++++ b/libnm-glib/nm-remote-connection.c +@@ -137,12 +137,14 @@ result_cb (DBusGProxy *proxy, DBusGProxyCall *proxy_call, gpointer user_data) + RemoteCall *call = user_data; + NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GError *error = NULL; ++ NMRemoteConnection *self = g_object_ref (call->self); + + dbus_g_proxy_end_call (proxy, proxy_call, &error, G_TYPE_INVALID); + if (func) + (*func) (call->self, error, call->user_data); + g_clear_error (&error); + remote_call_complete (call->self, call); ++ g_object_unref (self); + } + + /** +-- +1.7.11.7 + From 7212c621a9ba9a1f55357fdd52c99d6c80e0bec1 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 2 Dec 2013 15:02:03 -0500 Subject: [PATCH 12/15] core: Fix PtP/peer address support, for OpenVPN --- NetworkManager.spec | 9 +- rh1018317-openvpn-ptp.patch | 857 ++++++++++++++++++++++++++++++++++++ rh1018317-prereq.patch | 321 ++++++++++++++ 3 files changed, 1186 insertions(+), 1 deletion(-) create mode 100644 rh1018317-openvpn-ptp.patch create mode 100644 rh1018317-prereq.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 0484c57..360cf15 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 19%{snapshot}%{?dist} +Release: 20%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -43,6 +43,8 @@ Patch13: rh1025371-wifi-potential-crash.patch Patch14: rh1029053-fix-crash-device-no-MAC.patch Patch15: rh1030403-editor-crash-remote-connection.patch Patch16: fix-ifcfg-rh-con-update.patch +Patch17: rh1018317-prereq.patch +Patch18: rh1018317-openvpn-ptp.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -182,6 +184,8 @@ deployments. %patch14 -p1 -b .device-no-MAC %patch15 -p1 -b .libnm-glib-editor %patch16 -p1 -b .ifcfg-rh-update +%patch17 -p1 -b .ipv6-flags +%patch18 -p1 -b .openvpn-ptp %build @@ -380,6 +384,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Mon Dec 2 2013 Dan Winship - 0.9.9.0-20.git20131003 +- core: Fix PtP/peer address support, for OpenVPN (rh #1018317) + * Wed Nov 20 2013 Jiří Klimeš - 0.9.9.0-19.git20131003 - dispatcher: fix crash on exit while logging from signal handler (rh #1017884) - core: workaround crash when connecting to wifi (rh #1025371) diff --git a/rh1018317-openvpn-ptp.patch b/rh1018317-openvpn-ptp.patch new file mode 100644 index 0000000..09c9a6b --- /dev/null +++ b/rh1018317-openvpn-ptp.patch @@ -0,0 +1,857 @@ +From fec50bd5fad633e57bfd6f9ee480e6192504ca5f Mon Sep 17 00:00:00 2001 +From: Dan Winship +Date: Mon, 2 Dec 2013 10:20:26 -0500 +Subject: [PATCH] platform/core: add back support for PtP/peer addresses (rh + #1018317) + +In the migration to NMPlatform, support for ptp/peer addresses was +accidentally dropped. This broke OpenVPN configurations using 'p2p' +topology, which send a different peer address than the local address +for tunX, plus the server may also push routes that use the peer +address as the next hop. NetworkManager was unable to add these +routes, because the kernel had no idea how to talk to the peer, +because the peer's address was not assigned to any interface or +reachable over any routes. + +Partly based on a patch from Dan Williams. +--- + src/nm-ip4-config.c | 44 +--------------------------- + src/nm-ip4-config.h | 4 --- + src/nm-ip6-config.c | 49 ------------------------------- + src/nm-ip6-config.h | 4 --- + src/platform/nm-fake-platform.c | 10 +++++-- + src/platform/nm-linux-platform.c | 58 ++++++++++++++++++++++++++++++++----- + src/platform/nm-platform.c | 26 +++++++++++++---- + src/platform/nm-platform.h | 14 ++++++--- + src/platform/tests/platform.c | 4 +-- + src/platform/tests/test-address.c | 12 ++++---- + src/platform/tests/test-cleanup.c | 4 +-- + src/ppp-manager/nm-ppp-manager.c | 2 +- + src/tests/test-dhcp-options.c | 5 ++-- + src/tests/test-ip4-config.c | 12 ++++---- + src/tests/test-ip6-config.c | 13 ++++----- + src/vpn-manager/nm-vpn-connection.c | 10 +++---- + 16 files changed, 118 insertions(+), 153 deletions(-) + +diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c +index 7aff888..640a1e1 100644 +--- a/src/nm-ip4-config.c ++++ b/src/nm-ip4-config.c +@@ -47,7 +47,6 @@ typedef struct { + GPtrArray *domains; + GPtrArray *searches; + guint32 mss; +- guint32 ptp_address; + GArray *nis; + char *nis_domain; + GArray *wins; +@@ -454,10 +453,6 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src) + for (i = 0; i < nm_ip4_config_get_num_addresses (src); i++) + nm_ip4_config_add_address (dst, nm_ip4_config_get_address (src, i)); + +- /* ptp address; only replace if src doesn't have one */ +- if (!nm_ip4_config_get_ptp_address (dst)) +- nm_ip4_config_set_ptp_address (dst, nm_ip4_config_get_ptp_address (src)); +- + /* nameservers */ + for (i = 0; i < nm_ip4_config_get_num_nameservers (src); i++) + nm_ip4_config_add_nameserver (dst, nm_ip4_config_get_nameserver (src, i)); +@@ -527,10 +522,6 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src) + } + } + +- /* ptp address */ +- if (nm_ip4_config_get_ptp_address (src) == nm_ip4_config_get_ptp_address (dst)) +- nm_ip4_config_set_ptp_address (dst, 0); +- + /* nameservers */ + for (i = 0; i < nm_ip4_config_get_num_nameservers (src); i++) { + guint32 src_ns = nm_ip4_config_get_nameserver (src, i); +@@ -788,12 +779,6 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev + has_minor_changes = TRUE; + } + +- /* ptp address */ +- if (src_priv->ptp_address != dst_priv->ptp_address) { +- dst_priv->ptp_address = src_priv->ptp_address; +- has_relevant_changes = TRUE; +- } +- + /* nis */ + num = nm_ip4_config_get_num_nis_servers (src); + are_equal = num == nm_ip4_config_get_num_nis_servers (dst); +@@ -873,11 +858,6 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail) + } + } + +- /* ptp address */ +- tmp = nm_ip4_config_get_ptp_address (config); +- if (inet_ntop (AF_INET, (void *) &tmp, buf, sizeof (buf))) +- g_message (" ptp: %s", buf); +- + /* default gateway */ + tmp = nm_ip4_config_get_gateway (config); + if (inet_ntop (AF_INET, (void *) &tmp, buf, sizeof (buf))) +@@ -1314,24 +1294,6 @@ nm_ip4_config_get_mss (const NMIP4Config *config) + /******************************************************************/ + + void +-nm_ip4_config_set_ptp_address (NMIP4Config *config, guint32 ptp_addr) +-{ +- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); +- +- priv->ptp_address = ptp_addr; +-} +- +-guint32 +-nm_ip4_config_get_ptp_address (const NMIP4Config *config) +-{ +- NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); +- +- return priv->ptp_address; +-} +- +-/******************************************************************/ +- +-void + nm_ip4_config_reset_nis_servers (NMIP4Config *config) + { + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); +@@ -1480,7 +1442,7 @@ hash_u32 (GChecksum *sum, guint32 n) + void + nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only) + { +- guint32 i, n; ++ guint32 i; + const char *s; + + g_return_if_fail (config); +@@ -1504,10 +1466,6 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only + hash_u32 (sum, route->metric); + } + +- n = nm_ip4_config_get_ptp_address (config); +- if (n) +- hash_u32 (sum, n); +- + for (i = 0; i < nm_ip4_config_get_num_nis_servers (config); i++) + hash_u32 (sum, nm_ip4_config_get_nis_server (config, i)); + +diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h +index 5b76fb4..d57cd52 100644 +--- a/src/nm-ip4-config.h ++++ b/src/nm-ip4-config.h +@@ -117,10 +117,6 @@ const char * nm_ip4_config_get_search (const NMIP4Config *config, guint i); + void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss); + guint32 nm_ip4_config_get_mss (const NMIP4Config *config); + +-/* PTP */ +-void nm_ip4_config_set_ptp_address (NMIP4Config *config, guint32 ptp_addr); +-guint32 nm_ip4_config_get_ptp_address (const NMIP4Config *config); +- + /* NIS */ + void nm_ip4_config_reset_nis_servers (NMIP4Config *config); + void nm_ip4_config_add_nis_server (NMIP4Config *config, guint32 nis); +diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c +index 65cbd0b..8eb79f2 100644 +--- a/src/nm-ip6-config.c ++++ b/src/nm-ip6-config.c +@@ -47,7 +47,6 @@ typedef struct { + GPtrArray *domains; + GPtrArray *searches; + guint32 mss; +- struct in6_addr ptp_address; + } NMIP6ConfigPrivate; + + +@@ -457,10 +456,6 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src) + for (i = 0; i < nm_ip6_config_get_num_addresses (src); i++) + nm_ip6_config_add_address (dst, nm_ip6_config_get_address (src, i)); + +- /* ptp address; only replace if src doesn't have one */ +- if (!nm_ip6_config_get_ptp_address (dst)) +- nm_ip6_config_set_ptp_address (dst, nm_ip6_config_get_ptp_address (src)); +- + /* nameservers */ + for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++) + nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i)); +@@ -535,12 +530,6 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) + } + } + +- /* ptp address */ +- src_tmp = nm_ip6_config_get_ptp_address (src); +- dst_tmp = nm_ip6_config_get_ptp_address (dst); +- if (src_tmp && dst_tmp && IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp)) +- nm_ip6_config_set_ptp_address (dst, NULL); +- + /* nameservers */ + for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++) { + const struct in6_addr *src_ns = nm_ip6_config_get_nameserver (src, i); +@@ -769,12 +758,6 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev + has_minor_changes = TRUE; + } + +- /* ptp address */ +- if (!IN6_ARE_ADDR_EQUAL (&src_priv->ptp_address, &dst_priv->ptp_address)) { +- nm_ip6_config_set_ptp_address (dst, &src_priv->ptp_address); +- has_relevant_changes = TRUE; +- } +- + /* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes + * regardless of config_equal. But config_equal must correspond to has_relevant_changes. */ + g_assert (config_equal == !has_relevant_changes); +@@ -1219,28 +1197,6 @@ nm_ip6_config_get_mss (const NMIP6Config *config) + + /******************************************************************/ + +-void +-nm_ip6_config_set_ptp_address (NMIP6Config *config, const struct in6_addr *ptp_address) +-{ +- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); +- +- if (ptp_address) +- priv->ptp_address = *ptp_address; +- else +- memset (&priv->ptp_address, 0, sizeof (priv->ptp_address)); +- +-} +- +-const struct in6_addr * +-nm_ip6_config_get_ptp_address (const NMIP6Config *config) +-{ +- NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); +- +- return IN6_IS_ADDR_UNSPECIFIED (&priv->ptp_address) ? NULL : &priv->ptp_address; +-} +- +-/******************************************************************/ +- + static inline void + hash_u32 (GChecksum *sum, guint32 n) + { +@@ -1260,7 +1216,6 @@ void + nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only) + { + guint32 i; +- const struct in6_addr *in6a; + const char *s; + + g_return_if_fail (config); +@@ -1284,10 +1239,6 @@ nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only + hash_in6addr (sum, &route->gateway); + hash_u32 (sum, route->metric); + } +- +- in6a = nm_ip6_config_get_ptp_address (config); +- if (in6a) +- hash_in6addr (sum, in6a); + } + + for (i = 0; i < nm_ip6_config_get_num_nameservers (config); i++) +diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h +index aecdab2..eb93d07 100644 +--- a/src/nm-ip6-config.h ++++ b/src/nm-ip6-config.h +@@ -116,10 +116,6 @@ const char * nm_ip6_config_get_search (const NMIP6Config *config, guint i); + void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss); + guint32 nm_ip6_config_get_mss (const NMIP6Config *config); + +-/* PTP */ +-void nm_ip6_config_set_ptp_address (NMIP6Config *config, const struct in6_addr *ptp_addr); +-const struct in6_addr *nm_ip6_config_get_ptp_address (const NMIP6Config *config); +- + void nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only); + gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b); + +diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c +index df5d5b8..dcbf932 100644 +--- a/src/platform/nm-fake-platform.c ++++ b/src/platform/nm-fake-platform.c +@@ -739,7 +739,9 @@ get_time (void) + } + + static gboolean +-ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, guint32 lifetime, guint32 preferred) ++ip4_address_add (NMPlatform *platform, int ifindex, ++ in_addr_t addr, in_addr_t peer_addr, ++ int plen, guint32 lifetime, guint32 preferred) + { + NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); + NMPlatformIP4Address address; +@@ -748,6 +750,7 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, gu + memset (&address, 0, sizeof (address)); + address.ifindex = ifindex; + address.address = addr; ++ address.peer_address = peer_addr; + address.plen = plen; + address.timestamp = get_time (); + address.lifetime = lifetime; +@@ -775,7 +778,9 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, gu + } + + static gboolean +-ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred, guint flags) ++ip6_address_add (NMPlatform *platform, int ifindex, ++ struct in6_addr addr, struct in6_addr peer_addr, ++ int plen, guint32 lifetime, guint32 preferred, guint flags) + { + NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); + NMPlatformIP6Address address; +@@ -784,6 +789,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl + memset (&address, 0, sizeof (address)); + address.ifindex = ifindex; + address.address = addr; ++ address.peer_address = peer_addr; + address.plen = plen; + address.timestamp = get_time (); + address.lifetime = lifetime; +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index d13abbe..50b027a 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -764,6 +764,7 @@ static void + init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr) + { + struct nl_addr *nladdr = rtnl_addr_get_local (rtnladdr); ++ struct nl_addr *nlpeer = rtnl_addr_get_peer (rtnladdr); + + g_assert (nladdr); + +@@ -776,12 +777,17 @@ init_ip4_address (NMPlatformIP4Address *address, struct rtnl_addr *rtnladdr) + address->preferred = rtnl_addr_get_preferred_lifetime (rtnladdr); + g_assert (nl_addr_get_len (nladdr) == sizeof (address->address)); + memcpy (&address->address, nl_addr_get_binary_addr (nladdr), sizeof (address->address)); ++ if (nlpeer) { ++ g_assert (nl_addr_get_len (nlpeer) == sizeof (address->peer_address)); ++ memcpy (&address->peer_address, nl_addr_get_binary_addr (nlpeer), sizeof (address->peer_address)); ++ } + } + + static void + init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) + { + struct nl_addr *nladdr = rtnl_addr_get_local (rtnladdr); ++ struct nl_addr *nlpeer = rtnl_addr_get_peer (rtnladdr); + + memset (address, 0, sizeof (*address)); + +@@ -793,6 +799,10 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) + address->flags = rtnl_addr_get_flags (rtnladdr); + g_assert (nl_addr_get_len (nladdr) == sizeof (address->address)); + memcpy (&address->address, nl_addr_get_binary_addr (nladdr), sizeof (address->address)); ++ if (nlpeer) { ++ g_assert (nl_addr_get_len (nlpeer) == sizeof (address->peer_address)); ++ memcpy (&address->peer_address, nl_addr_get_binary_addr (nlpeer), sizeof (address->peer_address)); ++ } + } + + static gboolean +@@ -2208,7 +2218,14 @@ ip6_address_get_all (NMPlatform *platform, int ifindex) + } + + static struct nl_object * +-build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 lifetime, guint32 preferred, guint flags) ++build_rtnl_addr (int family, ++ int ifindex, ++ gconstpointer addr, ++ gconstpointer peer_addr, ++ int plen, ++ guint32 lifetime, ++ guint32 preferred, ++ guint flags) + { + struct rtnl_addr *rtnladdr = rtnl_addr_alloc (); + int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); +@@ -2220,6 +2237,14 @@ build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 + rtnl_addr_set_ifindex (rtnladdr, ifindex); + nle = rtnl_addr_set_local (rtnladdr, nladdr); + g_assert (!nle); ++ ++ if (peer_addr) { ++ auto_nl_addr struct nl_addr *nlpeer = nl_addr_build (family, peer_addr, addrlen); ++ ++ nle = rtnl_addr_set_peer (rtnladdr, nlpeer); ++ g_assert (!nle); ++ } ++ + rtnl_addr_set_prefixlen (rtnladdr, plen); + if (lifetime) { + rtnl_addr_set_valid_lifetime (rtnladdr, lifetime); +@@ -2232,33 +2257,50 @@ build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 + } + + static gboolean +-ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, guint32 lifetime, guint32 preferred) ++ip4_address_add (NMPlatform *platform, ++ int ifindex, ++ in_addr_t addr, ++ in_addr_t peer_addr, ++ int plen, ++ guint32 lifetime, ++ guint32 preferred) + { +- return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, lifetime, preferred, 0)); ++ return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, ++ peer_addr ? &peer_addr : NULL, ++ plen, lifetime, preferred, 0)); + } + + static gboolean +-ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred, guint flags) ++ip6_address_add (NMPlatform *platform, ++ int ifindex, ++ struct in6_addr addr, ++ struct in6_addr peer_addr, ++ int plen, ++ guint32 lifetime, ++ guint32 preferred, ++ guint flags) + { +- return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, lifetime, preferred, flags)); ++ return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, ++ memcmp (&peer_addr, &in6addr_any, sizeof (struct in6_addr)) == 0 ? NULL : &peer_addr, ++ plen, lifetime, preferred, flags)); + } + + static gboolean + ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) + { +- return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, 0, 0, 0)); ++ return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0)); + } + + static gboolean + ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) + { +- return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, 0, 0, 0)); ++ return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, NULL, plen, 0, 0, 0)); + } + + static gboolean + ip_address_exists (NMPlatform *platform, int family, int ifindex, gconstpointer addr, int plen) + { +- auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, plen, 0, 0, 0); ++ auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, NULL, plen, 0, 0, 0); + auto_nl_object struct nl_object *cached_object = nl_cache_search (choose_cache (platform, object), object); + + return !!cached_object; +diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c +index 3f7f054..4e9c8fc 100644 +--- a/src/platform/nm-platform.c ++++ b/src/platform/nm-platform.c +@@ -1165,7 +1165,12 @@ nm_platform_ip6_address_get_all (int ifindex) + } + + gboolean +-nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, guint32 lifetime, guint32 preferred) ++nm_platform_ip4_address_add (int ifindex, ++ in_addr_t address, ++ in_addr_t peer_address, ++ int plen, ++ guint32 lifetime, ++ guint32 preferred) + { + reset_error (); + +@@ -1175,11 +1180,17 @@ nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, guint32 l + g_return_val_if_fail (klass->ip4_address_add, FALSE); + + debug ("address: adding or updating IPv4 address"); +- return klass->ip4_address_add (platform, ifindex, address, plen, lifetime, preferred); ++ return klass->ip4_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred); + } + + gboolean +-nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, guint32 lifetime, guint32 preferred, guint flags) ++nm_platform_ip6_address_add (int ifindex, ++ struct in6_addr address, ++ struct in6_addr peer_address, ++ int plen, ++ guint32 lifetime, ++ guint32 preferred, ++ guint flags) + { + reset_error (); + +@@ -1189,7 +1200,7 @@ nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, gui + g_return_val_if_fail (klass->ip6_address_add, FALSE); + + debug ("address: adding or updating IPv6 address"); +- return klass->ip6_address_add (platform, ifindex, address, plen, lifetime, preferred, flags); ++ return klass->ip6_address_add (platform, ifindex, address, peer_address, plen, lifetime, preferred, flags); + } + + gboolean +@@ -1350,7 +1361,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + +- if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) ++ if (!nm_platform_ip4_address_add (ifindex, known_address->address, known_address->peer_address, known_address->plen, lifetime, preferred)) + return FALSE; + } + +@@ -1407,7 +1418,8 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + +- if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, ++ if (!nm_platform_ip6_address_add (ifindex, known_address->address, ++ known_address->peer_address, known_address->plen, + lifetime, preferred, known_address->flags)) + return FALSE; + } +@@ -1843,6 +1855,7 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A + { + _CMP_POINTER (a, b); + _CMP_FIELD_MEMCMP (a, b, address); ++ _CMP_FIELD_MEMCMP (a, b, peer_address); + _CMP_FIELD (a, b, ifindex); + _CMP_FIELD (a, b, plen); + _CMP_FIELD (a, b, timestamp); +@@ -1857,6 +1870,7 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A + _CMP_POINTER (a, b); + _CMP_FIELD (a, b, ifindex); + _CMP_FIELD_MEMCMP (a, b, address); ++ _CMP_FIELD_MEMCMP (a, b, peer_address); + _CMP_FIELD (a, b, plen); + _CMP_FIELD (a, b, timestamp); + _CMP_FIELD (a, b, lifetime); +diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h +index ff338fc..b742c39 100644 +--- a/src/platform/nm-platform.h ++++ b/src/platform/nm-platform.h +@@ -122,6 +122,7 @@ typedef struct { + typedef struct { + int ifindex; + in_addr_t address; ++ in_addr_t peer_address; /* PTP peer address */ + int plen; + guint32 timestamp; + guint32 lifetime; +@@ -131,6 +132,7 @@ typedef struct { + typedef struct { + int ifindex; + struct in6_addr address; ++ struct in6_addr peer_address; + int plen; + guint32 timestamp; + guint32 lifetime; +@@ -280,9 +282,11 @@ typedef struct { + + GArray * (*ip4_address_get_all) (NMPlatform *, int ifindex); + GArray * (*ip6_address_get_all) (NMPlatform *, int ifindex); +- gboolean (*ip4_address_add) (NMPlatform *, int ifindex, in_addr_t address, int plen, +- guint32 lifetime, guint32 preferred_lft); +- gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, int plen, ++ gboolean (*ip4_address_add) (NMPlatform *, int ifindex, ++ in_addr_t address, in_addr_t peer_address, int plen, ++ guint32 lifetime, guint32 preferred_lft); ++ 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 (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen); +@@ -402,9 +406,11 @@ gboolean nm_platform_gre_get_properties (int ifindex, NMPlatformGreProperties *p + + GArray *nm_platform_ip4_address_get_all (int ifindex); + GArray *nm_platform_ip6_address_get_all (int ifindex); +-gboolean nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, +- guint32 lifetime, guint32 preferred_lft); +-gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, ++gboolean nm_platform_ip4_address_add (int ifindex, ++ in_addr_t address, in_addr_t peer_address, int plen, ++ guint32 lifetime, guint32 preferred_lft); ++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_ip6_address_delete (int ifindex, struct in6_addr address, int plen); +diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c +index c0b2c02..7ca2cb5 100644 +--- a/src/platform/tests/platform.c ++++ b/src/platform/tests/platform.c +@@ -523,7 +523,7 @@ do_ip4_address_add (char **argv) + guint32 lifetime = strtol (*argv++, NULL, 10); + guint32 preferred = strtol (*argv++, NULL, 10); + +- gboolean value = nm_platform_ip4_address_add (ifindex, address, plen, lifetime, preferred); ++ gboolean value = nm_platform_ip4_address_add (ifindex, address, 0, plen, lifetime, preferred); + return value; + } else + return FALSE; +@@ -541,7 +541,7 @@ do_ip6_address_add (char **argv) + guint32 preferred = strtol (*argv++, NULL, 10); + guint flags = (*argv) ? rtnl_addr_str2flags (*argv++) : 0; + +- gboolean value = nm_platform_ip6_address_add (ifindex, address, plen, lifetime, preferred, flags); ++ gboolean value = nm_platform_ip6_address_add (ifindex, address, in6addr_any, plen, lifetime, preferred, flags); + return value; + } else + return FALSE; +diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c +index 52952c3..0f0ccc8 100644 +--- a/src/platform/tests/test-address.c ++++ b/src/platform/tests/test-address.c +@@ -60,14 +60,14 @@ test_ip4_address (void) + /* Add address */ + g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); + no_error (); +- g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred)); + no_error (); + g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); + no_error (); + accept_signal (address_added); + + /* Add address again (aka update) */ +- g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred)); + no_error (); + accept_signal (address_changed); + +@@ -116,14 +116,14 @@ test_ip6_address (void) + /* Add address */ + g_assert (!nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + no_error (); +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + no_error (); + accept_signal (address_added); + + /* Add address again (aka update) */ +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + accept_signal (address_changed); + +@@ -183,7 +183,7 @@ test_ip4_address_external (void) + /* Add/delete conflict */ + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP4_ADDRESS, IP4_PLEN, DEVICE_NAME, lifetime, preferred); +- g_assert (nm_platform_ip4_address_add (ifindex, addr, IP4_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip4_address_add (ifindex, addr, 0, IP4_PLEN, lifetime, preferred)); + no_error (); + g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); + accept_signal (address_added); +@@ -222,7 +222,7 @@ test_ip6_address_external (void) + /* Add/delete conflict */ + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred); +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, in6addr_any, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + accept_signal (address_added); +diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c +index f102870..d94b359 100644 +--- a/src/platform/tests/test-cleanup.c ++++ b/src/platform/tests/test-cleanup.c +@@ -41,8 +41,8 @@ test_cleanup_internal () + g_assert (ifindex > 0); + + /* Add routes and addresses */ +- g_assert (nm_platform_ip4_address_add (ifindex, addr4, plen4, lifetime, preferred)); +- g_assert (nm_platform_ip6_address_add (ifindex, addr6, plen6, lifetime, preferred, flags)); ++ g_assert (nm_platform_ip4_address_add (ifindex, addr4, 0, plen4, lifetime, preferred)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr6, in6addr_any, plen6, lifetime, preferred, flags)); + g_assert (nm_platform_ip4_route_add (ifindex, gateway4, 32, INADDR_ANY, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, network4, plen4, gateway4, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway4, metric, mss)); +diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c +index ffb1e74..b2f2326 100644 +--- a/src/ppp-manager/nm-ppp-manager.c ++++ b/src/ppp-manager/nm-ppp-manager.c +@@ -538,7 +538,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, + val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_GATEWAY); + if (val) { + nm_ip4_config_set_gateway (config, g_value_get_uint (val)); +- nm_ip4_config_set_ptp_address (config, g_value_get_uint (val)); ++ address.peer_address = g_value_get_uint (val); + } + + val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_ADDRESS); +diff --git a/src/tests/test-dhcp-options.c b/src/tests/test-dhcp-options.c +index effe658..6ef599e 100644 +--- a/src/tests/test-dhcp-options.c ++++ b/src/tests/test-dhcp-options.c +@@ -129,6 +129,8 @@ test_generic_options (const char *client) + "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"); +@@ -139,9 +141,6 @@ test_generic_options (const char *client) + ASSERT (nm_ip4_config_get_gateway (ip4_config) == tmp, + "dhcp-generic", "unexpected IP gateway"); + +- ASSERT (nm_ip4_config_get_ptp_address (ip4_config) == 0, +- "dhcp-generic", "unexpected PTP address"); +- + ASSERT (nm_ip4_config_get_num_wins (ip4_config) == 0, + "dhcp-generic", "unexpected number of WINS servers"); + +diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c +index 331897c..fde4a40 100644 +--- a/src/tests/test-ip4-config.c ++++ b/src/tests/test-ip4-config.c +@@ -25,10 +25,12 @@ + #include "nm-ip4-config.h" + + static void +-addr_init (NMPlatformIP4Address *a, const char *addr, guint plen) ++addr_init (NMPlatformIP4Address *a, const char *addr, const char *peer, guint plen) + { + memset (a, 0, sizeof (*a)); + g_assert (inet_pton (AF_INET, addr, (void *) &a->address) == 1); ++ if (peer) ++ g_assert (inet_pton (AF_INET, peer, (void *) &a->peer_address) == 1); + a->plen = plen; + } + +@@ -68,7 +70,7 @@ build_test_config (void) + /* Build up the config to subtract */ + config = nm_ip4_config_new (); + +- addr_init (&addr, "192.168.1.10", 24); ++ addr_init (&addr, "192.168.1.10", "1.2.3.4", 24); + nm_ip4_config_add_address (config, &addr); + + route_new (&route, "10.0.0.0", 8, "192.168.1.1"); +@@ -86,8 +88,6 @@ build_test_config (void) + nm_ip4_config_add_search (config, "blahblah.com"); + nm_ip4_config_add_search (config, "beatbox.com"); + +- nm_ip4_config_set_ptp_address (config, addr_to_num ("1.2.3.4")); +- + nm_ip4_config_add_nis_server (config, addr_to_num ("1.2.3.9")); + nm_ip4_config_add_nis_server (config, addr_to_num ("1.2.3.10")); + +@@ -121,7 +121,7 @@ test_subtract (void) + + /* add a couple more things to the test config */ + dst = build_test_config (); +- addr_init (&addr, expected_addr, expected_addr_plen); ++ addr_init (&addr, expected_addr, NULL, expected_addr_plen); + nm_ip4_config_add_address (dst, &addr); + + route_new (&route, expected_route_dest, expected_route_plen, expected_route_next_hop); +@@ -142,9 +142,9 @@ test_subtract (void) + test_addr = nm_ip4_config_get_address (dst, 0); + g_assert (test_addr != NULL); + g_assert_cmpuint (test_addr->address, ==, addr_to_num (expected_addr)); ++ g_assert_cmpuint (test_addr->peer_address, ==, 0); + g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen); + +- g_assert_cmpuint (nm_ip4_config_get_ptp_address (dst), ==, 0); + g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0); + + g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1); +diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c +index 10ce3bf..b8b9c7b 100644 +--- a/src/tests/test-ip6-config.c ++++ b/src/tests/test-ip6-config.c +@@ -25,10 +25,12 @@ + #include "nm-ip6-config.h" + + static void +-addr_init (NMPlatformIP6Address *a, const char *addr, guint plen) ++addr_init (NMPlatformIP6Address *a, const char *addr, const char *peer, guint plen) + { + memset (a, 0, sizeof (*a)); + g_assert (inet_pton (AF_INET6, addr, (void *) &a->address) == 1); ++ if (peer) ++ g_assert (inet_pton (AF_INET6, peer, (void *) &a->peer_address) == 1); + a->plen = plen; + } + +@@ -61,7 +63,7 @@ build_test_config (void) + /* Build up the config to subtract */ + config = nm_ip6_config_new (); + +- addr_init (&addr, "abcd:1234:4321::cdde", 64); ++ addr_init (&addr, "abcd:1234:4321::cdde", "1:2:3:4::5", 64); + nm_ip6_config_add_address (config, &addr); + + route_new (&route, "abcd:1234:4321::", 24, "abcd:1234:4321:cdde::2"); +@@ -82,9 +84,6 @@ build_test_config (void) + nm_ip6_config_add_search (config, "blahblah.com"); + nm_ip6_config_add_search (config, "beatbox.com"); + +- addr_to_num ("1:2:3:4::5", &tmp); +- nm_ip6_config_set_ptp_address (config, &tmp); +- + return config; + } + +@@ -111,7 +110,7 @@ test_subtract (void) + + /* add a couple more things to the test config */ + dst = build_test_config (); +- addr_init (&addr, expected_addr, expected_addr_plen); ++ addr_init (&addr, expected_addr, NULL, expected_addr_plen); + nm_ip6_config_add_address (dst, &addr); + + route_new (&route, expected_route_dest, expected_route_plen, expected_route_next_hop); +@@ -133,9 +132,9 @@ test_subtract (void) + g_assert (test_addr != NULL); + addr_to_num (expected_addr, &tmp); + g_assert (memcmp (&test_addr->address, &tmp, sizeof (tmp)) == 0); ++ g_assert (memcmp (&test_addr->peer_address, &in6addr_any, sizeof (tmp)) == 0); + g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen); + +- g_assert (nm_ip6_config_get_ptp_address (dst) == NULL); + g_assert (nm_ip6_config_get_gateway (dst) == NULL); + + g_assert_cmpuint (nm_ip6_config_get_num_routes (dst), ==, 1); +diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c +index a3b09f2..2d53449 100644 +--- a/src/vpn-manager/nm-vpn-connection.c ++++ b/src/vpn-manager/nm-vpn-connection.c +@@ -569,8 +569,7 @@ print_vpn_config (NMVPNConnection *connection) + nm_log_info (LOGD_VPN, " Internal Gateway: %s", ip_address_to_string (priv->ip4_internal_gw)); + nm_log_info (LOGD_VPN, " Internal Address: %s", ip_address_to_string (address4->address)); + nm_log_info (LOGD_VPN, " Internal Prefix: %d", address4->plen); +- nm_log_info (LOGD_VPN, " Internal Point-to-Point Address: %s", +- ip_address_to_string (nm_ip4_config_get_ptp_address (priv->ip4_config))); ++ nm_log_info (LOGD_VPN, " Internal Point-to-Point Address: %s", ip_address_to_string (address4->peer_address)); + nm_log_info (LOGD_VPN, " Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (priv->ip4_config)); + + num = nm_ip4_config_get_num_routes (priv->ip4_config); +@@ -610,8 +609,7 @@ print_vpn_config (NMVPNConnection *connection) + nm_log_info (LOGD_VPN, " Internal Gateway: %s", ip6_address_to_string (priv->ip6_internal_gw)); + nm_log_info (LOGD_VPN, " Internal Address: %s", ip6_address_to_string (&address6->address)); + nm_log_info (LOGD_VPN, " Internal Prefix: %d", address6->plen); +- nm_log_info (LOGD_VPN, " Internal Point-to-Point Address: %s", +- ip6_address_to_string (nm_ip6_config_get_ptp_address (priv->ip6_config))); ++ nm_log_info (LOGD_VPN, " Internal Point-to-Point Address: %s", ip6_address_to_string (&address6->peer_address)); + nm_log_info (LOGD_VPN, " Maximum Segment Size (MSS): %d", nm_ip6_config_get_mss (priv->ip6_config)); + + num = nm_ip6_config_get_num_routes (priv->ip6_config); +@@ -876,7 +874,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, + + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PTP); + if (val) +- nm_ip4_config_set_ptp_address (config, g_value_get_uint (val)); ++ address.peer_address = g_value_get_uint (val); + + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX); + if (val) +@@ -1024,7 +1022,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy, + GByteArray *ba = g_value_get_boxed (val); + + if (ba->len == sizeof (struct in6_addr)) +- nm_ip6_config_set_ptp_address (config, (struct in6_addr *)ba->data); ++ address.peer_address = *(struct in6_addr *) ba->data; + } + + val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP6_CONFIG_PREFIX); +-- +1.8.4.2 + diff --git a/rh1018317-prereq.patch b/rh1018317-prereq.patch new file mode 100644 index 0000000..e5f8f4a --- /dev/null +++ b/rh1018317-prereq.patch @@ -0,0 +1,321 @@ +From ac94d83f04d87971c8bea4e164d7a5e260720e5c Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 15 Oct 2013 20:44:59 +0200 +Subject: [PATCH] core: add ifa_flags to NMPlatformIP6Address structure + +Add a field 'flags' to NMPlatformIP6Address that holds the +IFA_F_* flags as reported over netlink. + +Signed-off-by: Thomas Haller +--- + src/platform/nm-fake-platform.c | 3 ++- + src/platform/nm-linux-platform.c | 17 ++++++++++------- + src/platform/nm-platform.c | 20 +++++++++++++++----- + src/platform/nm-platform.h | 6 ++++-- + src/platform/tests/platform.c | 6 ++++-- + src/platform/tests/test-address.c | 8 +++++--- + src/platform/tests/test-cleanup.c | 3 ++- + 7 files changed, 42 insertions(+), 21 deletions(-) + +diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c +index 491e23e..df5d5b8 100644 +--- a/src/platform/nm-fake-platform.c ++++ b/src/platform/nm-fake-platform.c +@@ -775,7 +775,7 @@ ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, gu + } + + static gboolean +-ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred) ++ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred, guint flags) + { + NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); + NMPlatformIP6Address address; +@@ -788,6 +788,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int pl + address.timestamp = get_time (); + address.lifetime = lifetime; + address.preferred = preferred; ++ address.flags = flags; + + for (i = 0; i < priv->ip6_addresses->len; i++) { + NMPlatformIP6Address *item = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i); +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index 0f67180..e3d6357 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -790,6 +790,7 @@ init_ip6_address (NMPlatformIP6Address *address, struct rtnl_addr *rtnladdr) + address->timestamp = rtnl_addr_get_create_time (rtnladdr); + address->lifetime = rtnl_addr_get_valid_lifetime (rtnladdr); + address->preferred = rtnl_addr_get_preferred_lifetime (rtnladdr); ++ address->flags = rtnl_addr_get_flags (rtnladdr); + g_assert (nl_addr_get_len (nladdr) == sizeof (address->address)); + memcpy (&address->address, nl_addr_get_binary_addr (nladdr), sizeof (address->address)); + } +@@ -2198,7 +2199,7 @@ ip6_address_get_all (NMPlatform *platform, int ifindex) + } + + static struct nl_object * +-build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 lifetime, guint32 preferred) ++build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 lifetime, guint32 preferred, guint flags) + { + struct rtnl_addr *rtnladdr = rtnl_addr_alloc (); + int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); +@@ -2215,6 +2216,8 @@ build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 + rtnl_addr_set_valid_lifetime (rtnladdr, lifetime); + rtnl_addr_set_preferred_lifetime (rtnladdr, preferred); + } ++ if (flags) ++ rtnl_addr_set_flags (rtnladdr, flags); + + return (struct nl_object *) rtnladdr; + } +@@ -2222,31 +2225,31 @@ build_rtnl_addr (int family, int ifindex, gconstpointer addr, int plen, guint32 + static gboolean + ip4_address_add (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, guint32 lifetime, guint32 preferred) + { +- return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, lifetime, preferred)); ++ return add_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, lifetime, preferred, 0)); + } + + static gboolean +-ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred) ++ip6_address_add (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen, guint32 lifetime, guint32 preferred, guint flags) + { +- return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, lifetime, preferred)); ++ return add_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, lifetime, preferred, flags)); + } + + static gboolean + ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) + { +- return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, 0, 0)); ++ return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, plen, 0, 0, 0)); + } + + static gboolean + ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, int plen) + { +- return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, 0, 0)); ++ return delete_object (platform, build_rtnl_addr (AF_INET6, ifindex, &addr, plen, 0, 0, 0)); + } + + static gboolean + ip_address_exists (NMPlatform *platform, int family, int ifindex, gconstpointer addr, int plen) + { +- auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, plen, 0, 0); ++ auto_nl_object struct nl_object *object = build_rtnl_addr (family, ifindex, addr, plen, 0, 0, 0); + auto_nl_object struct nl_object *cached_object = nl_cache_search (choose_cache (platform, object), object); + + return !!cached_object; +diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c +index 5a5e464..3f645ed 100644 +--- a/src/platform/nm-platform.c ++++ b/src/platform/nm-platform.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "nm-platform.h" + #include "nm-logging.h" +@@ -1100,7 +1101,7 @@ nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, guint32 l + } + + gboolean +-nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, guint32 lifetime, guint32 preferred) ++nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, guint32 lifetime, guint32 preferred, guint flags) + { + reset_error (); + +@@ -1111,7 +1112,7 @@ nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, gui + g_return_val_if_fail (klass->ip6_address_add, FALSE); + + debug ("address: adding or updating IPv6 address"); +- return klass->ip6_address_add (platform, ifindex, address, plen, lifetime, preferred); ++ return klass->ip6_address_add (platform, ifindex, address, plen, lifetime, preferred, flags); + } + + gboolean +@@ -1329,7 +1330,8 @@ nm_platform_ip6_address_sync (int ifindex, const GArray *known_addresses) + } else + lifetime = preferred = NM_PLATFORM_LIFETIME_PERMANENT; + +- if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, lifetime, preferred)) ++ if (!nm_platform_ip6_address_add (ifindex, known_address->address, known_address->plen, ++ lifetime, preferred, known_address->flags)) + return FALSE; + } + +@@ -1637,8 +1639,10 @@ const char * + nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address) + { + static char buffer[256]; ++ char s_flags[256]; + char s_address[INET6_ADDRSTRLEN]; + const char *s_dev; ++ char *str_flags; + + g_return_val_if_fail (address, "(unknown)"); + +@@ -1648,7 +1652,12 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address) + s_dev = address->ifindex > 0 ? nm_platform_link_get_name (address->ifindex) : NULL; + +- g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u dev %s", ++ rtnl_addr_flags2str(address->flags, s_flags, sizeof(s_flags)); ++ str_flags = s_flags[0] ? g_strconcat (" flags ", s_flags, NULL) : NULL; ++ ++ g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u dev %s%s", + s_address, address->plen, (guint)address->lifetime, (guint)address->preferred, +- (guint)address->timestamp, s_dev ? s_dev : "-"); ++ (guint)address->timestamp, s_dev ? s_dev : "-", ++ str_flags ? str_flags : ""); ++ g_free (str_flags); + return buffer; + } +@@ -1775,6 +1784,7 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A + _CMP_FIELD (a, b, timestamp); + _CMP_FIELD (a, b, lifetime); + _CMP_FIELD (a, b, preferred); ++ _CMP_FIELD (a, b, flags); + return 0; + } + +diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h +index eae5465..7de0280 100644 +--- a/src/platform/nm-platform.h ++++ b/src/platform/nm-platform.h +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define NM_TYPE_PLATFORM (nm_platform_get_type ()) + #define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform)) +@@ -134,6 +135,7 @@ typedef struct { + guint32 timestamp; + guint32 lifetime; + guint32 preferred; ++ guint flags; /* ifa_flags from , field type "unsigned int" is as used in rtnl_addr_get_flags. */ + } NMPlatformIP6Address; + + typedef struct { +@@ -281,7 +283,7 @@ typedef struct { + gboolean (*ip4_address_add) (NMPlatform *, int ifindex, in_addr_t address, int plen, + guint32 lifetime, guint32 preferred_lft); + gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, int plen, +- guint32 lifetime, guint32 preferred_lft); ++ guint32 lifetime, guint32 preferred_lft, guint flags); + gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen); + 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); +@@ -402,7 +404,7 @@ GArray *nm_platform_ip6_address_get_all (int ifindex); + gboolean nm_platform_ip4_address_add (int ifindex, in_addr_t address, int plen, + guint32 lifetime, guint32 preferred_lft); + gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, int plen, +- guint32 lifetime, guint32 preferred_lft); ++ guint32 lifetime, guint32 preferred_lft, guint flags); + gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen); + 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); +diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c +index cd274cd..c0b2c02 100644 +--- a/src/platform/tests/platform.c ++++ b/src/platform/tests/platform.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include "nm-platform.h" + #include "nm-linux-platform.h" +@@ -538,8 +539,9 @@ do_ip6_address_add (char **argv) + if (ifindex && parse_ip6_address (*argv++, &address, &plen)) { + guint32 lifetime = strtol (*argv++, NULL, 10); + guint32 preferred = strtol (*argv++, NULL, 10); ++ guint flags = (*argv) ? rtnl_addr_str2flags (*argv++) : 0; + +- gboolean value = nm_platform_ip6_address_add (ifindex, address, plen, lifetime, preferred); ++ gboolean value = nm_platform_ip6_address_add (ifindex, address, plen, lifetime, preferred, flags); + return value; + } else + return FALSE; +@@ -765,7 +767,7 @@ static const command_t commands[] = { + { "ip4-address-get-all", "print all IPv4 addresses", do_ip4_address_get_all, 1, "" }, + { "ip6-address-get-all", "print all IPv6 addresses", do_ip6_address_get_all, 1, "" }, + { "ip4-address-add", "add IPv4 address", do_ip4_address_add, 4, "
/ <>" }, +- { "ip6-address-add", "add IPv6 address", do_ip6_address_add, 4, "
/ <>" }, ++ { "ip6-address-add", "add IPv6 address", do_ip6_address_add, 4, "
/ [] <>" }, + { "ip4-address-delete", "delete IPv4 address", do_ip4_address_delete, 2, + "
/" }, + { "ip6-address-delete", "delete IPv6 address", do_ip6_address_delete, 2, +diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c +index ff11384..52952c3 100644 +--- a/src/platform/tests/test-address.c ++++ b/src/platform/tests/test-address.c +@@ -109,20 +109,21 @@ test_ip6_address (void) + struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; ++ guint flags = 0; + + inet_pton (AF_INET6, IP6_ADDRESS, &addr); + + /* Add address */ + g_assert (!nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + no_error (); +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + no_error (); + accept_signal (address_added); + + /* Add address again (aka update) */ +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + accept_signal (address_changed); + +@@ -205,6 +206,7 @@ test_ip6_address_external (void) + struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; ++ guint flags = 0; + + inet_pton (AF_INET6, IP6_ADDRESS, &addr); + +@@ -220,7 +222,7 @@ test_ip6_address_external (void) + /* Add/delete conflict */ + run_command ("ip address add %s/%d dev %s valid_lft %d preferred_lft %d", + IP6_ADDRESS, IP6_PLEN, DEVICE_NAME, lifetime, preferred); +- g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr, IP6_PLEN, lifetime, preferred, flags)); + no_error (); + g_assert (nm_platform_ip6_address_exists (ifindex, addr, IP6_PLEN)); + accept_signal (address_added); +diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c +index cbfebe7..f102870 100644 +--- a/src/platform/tests/test-cleanup.c ++++ b/src/platform/tests/test-cleanup.c +@@ -23,6 +23,7 @@ test_cleanup_internal () + int preferred = NM_PLATFORM_LIFETIME_PERMANENT; + int metric = 20; + int mss = 1000; ++ guint flags = 0; + + inet_pton (AF_INET, "192.0.2.1", &addr4); + inet_pton (AF_INET, "192.0.3.0", &network4); +@@ -41,7 +42,7 @@ test_cleanup_internal () + + /* Add routes and addresses */ + g_assert (nm_platform_ip4_address_add (ifindex, addr4, plen4, lifetime, preferred)); +- g_assert (nm_platform_ip6_address_add (ifindex, addr6, plen6, lifetime, preferred)); ++ g_assert (nm_platform_ip6_address_add (ifindex, addr6, plen6, lifetime, preferred, flags)); + g_assert (nm_platform_ip4_route_add (ifindex, gateway4, 32, INADDR_ANY, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, network4, plen4, gateway4, metric, mss)); + g_assert (nm_platform_ip4_route_add (ifindex, 0, 0, gateway4, metric, mss)); +-- +1.8.4.2 + From 170f1c14b71bcf700325a0cd55f46ebe669effde Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 18 Dec 2013 13:03:30 -0600 Subject: [PATCH 13/15] Fix a couple bugs (rh #1034921) (rh #1029213) (rh #1032819) - core: wait for link before declaring startup complete (rh #1034921) - core: ignore RA-provided IPv6 default routes (rh #1029213) - core: set IPv4 broadcast address correctly (rh #1032819) --- NetworkManager.spec | 13 +- rh1029213-ignore-RA-default-routes.patch | 98 +++ rh1032819-set-broadcast-address.patch | 86 +++ rh1034921-startup-link-wait.patch | 833 +++++++++++++++++++++++ 4 files changed, 1029 insertions(+), 1 deletion(-) create mode 100644 rh1029213-ignore-RA-default-routes.patch create mode 100644 rh1032819-set-broadcast-address.patch create mode 100644 rh1034921-startup-link-wait.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 360cf15..001c6e9 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 20%{snapshot}%{?dist} +Release: 21%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -45,6 +45,9 @@ Patch15: rh1030403-editor-crash-remote-connection.patch Patch16: fix-ifcfg-rh-con-update.patch Patch17: rh1018317-prereq.patch Patch18: rh1018317-openvpn-ptp.patch +Patch19: rh1034921-startup-link-wait.patch +Patch20: rh1029213-ignore-RA-default-routes.patch +Patch21: rh1032819-set-broadcast-address.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -186,6 +189,9 @@ deployments. %patch16 -p1 -b .ifcfg-rh-update %patch17 -p1 -b .ipv6-flags %patch18 -p1 -b .openvpn-ptp +%patch19 -p1 -b .startup-linkwait +%patch20 -p1 -b .ignore-RA-default-routes +%patch21 -p1 -b .broadcast-addr %build @@ -384,6 +390,11 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Thu Dec 12 2013 Dan Williams - 0.9.9.0-21.git20131003 +- core: wait for link before declaring startup complete (rh #1034921) +- core: ignore RA-provided IPv6 default routes (rh #1029213) +- core: set IPv4 broadcast address correctly (rh #1032819) + * Mon Dec 2 2013 Dan Winship - 0.9.9.0-20.git20131003 - core: Fix PtP/peer address support, for OpenVPN (rh #1018317) diff --git a/rh1029213-ignore-RA-default-routes.patch b/rh1029213-ignore-RA-default-routes.patch new file mode 100644 index 0000000..e5b06d4 --- /dev/null +++ b/rh1029213-ignore-RA-default-routes.patch @@ -0,0 +1,98 @@ +From 8586353b09460ec0a619058421743dd7d424a75d Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 20 Nov 2013 13:40:07 -0600 +Subject: [PATCH] core: ignore RA-provided default routes (rh #1029213) + +The router has no idea what the local configuration or user preferences are, +so sending routes with a prefix length of 0 is at best misinformed and at +worst breaks things. The kernel also ignores plen=0 routes in its in-kernel +RA processing code in net/ipv6/ndisc.c. + +https://bugzilla.redhat.com/show_bug.cgi?id=1029213 +--- + src/devices/nm-device.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index f03ecbb..d92a94b 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -3283,20 +3283,26 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device + /* Rebuild route list from router discovery cache. */ + nm_ip6_config_reset_routes (priv->ac_ip6_config); + + for (i = 0; i < rdisc->routes->len; i++) { + NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i); + NMPlatformIP6Route route; + +- memset (&route, 0, sizeof (route)); +- route.network = discovered_route->network; +- route.plen = discovered_route->plen; +- route.gateway = discovered_route->gateway; ++ /* 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; + +- nm_ip6_config_add_route (priv->ac_ip6_config, &route); ++ nm_ip6_config_add_route (priv->ac_ip6_config, &route); ++ } + } + } + + if (changed & NM_RDISC_CONFIG_DNS_SERVERS) { + /* Rebuild DNS server list from router discovery cache. */ + nm_ip6_config_reset_nameservers (priv->ac_ip6_config); + +-- +1.8.3.1 + +From 6e73f01b6e69f44f8d9da4872fb796b9d80acac1 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Tue, 3 Dec 2013 14:12:55 -0600 +Subject: [PATCH] platform: fix possible out-of-bounds access with RA route + masking + +If the prefix length was 128, that could cause an access beyond the +end of the array. Found by Thomas Haller. +--- + src/rdisc/nm-lndp-rdisc.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c +index abcc3c2..3299b32 100644 +--- a/src/rdisc/nm-lndp-rdisc.c ++++ b/src/rdisc/nm-lndp-rdisc.c +@@ -411,17 +411,21 @@ set_address_masked (struct in6_addr *dst, struct in6_addr *src, guint8 plen) + guint nbytes = plen / 8; + guint nbits = plen % 8; + + g_return_if_fail (plen <= 128); + g_assert (src); + g_assert (dst); + +- memset (dst, 0, sizeof (*dst)); +- memcpy (dst, src, nbytes); +- dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits))); ++ if (plen >= 128) ++ *dst = *src; ++ else { ++ memset (dst, 0, sizeof (*dst)); ++ memcpy (dst, src, nbytes); ++ dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits))); ++ } + } + + 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); +-- +1.8.3.1 + diff --git a/rh1032819-set-broadcast-address.patch b/rh1032819-set-broadcast-address.patch new file mode 100644 index 0000000..dd3c0fb --- /dev/null +++ b/rh1032819-set-broadcast-address.patch @@ -0,0 +1,86 @@ +From 7eb12a5b21f87d7592ec2c5235d1ed90c4fac132 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Tue, 3 Dec 2013 11:42:28 -0600 +Subject: [PATCH] platform: set IPv4 broadcast address too (rh #1032819) + +When moving over the platform, setting of the IPv4 broadcast address +got lost. Bring it back. + +https://bugzilla.redhat.com/show_bug.cgi?id=1032819 +--- + src/platform/nm-linux-platform.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index 8f0e077..3f57925 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -2213,14 +2213,33 @@ ip6_address_get_all (NMPlatform *platform, int ifindex) + nl_object_unmark (object); + } + } + + return addresses; + } + ++static void ++addr4_to_broadcast (struct in_addr *dst, const struct in_addr *src, guint8 plen) ++{ ++ guint nbytes = plen / 8; ++ guint nbits = plen % 8; ++ ++ g_return_if_fail (plen <= 32); ++ g_assert (src); ++ g_assert (dst); ++ ++ if (plen >= 32) ++ *dst = *src; ++ else { ++ dst->s_addr = 0xFFFFFFFF; ++ memcpy (dst, src, nbytes); ++ ((guint8 *) dst)[nbytes] = (((const guint8 *) src)[nbytes] | (0xFF >> nbits)); ++ } ++} ++ + static struct nl_object * + build_rtnl_addr (int family, + int ifindex, + gconstpointer addr, + gconstpointer peer_addr, + int plen, + guint32 lifetime, +@@ -2230,18 +2249,31 @@ build_rtnl_addr (int family, + struct rtnl_addr *rtnladdr = rtnl_addr_alloc (); + int addrlen = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); + auto_nl_addr struct nl_addr *nladdr = nl_addr_build (family, addr, addrlen); + int nle; + + g_assert (rtnladdr && nladdr); + ++ /* IP address */ + rtnl_addr_set_ifindex (rtnladdr, ifindex); + nle = rtnl_addr_set_local (rtnladdr, nladdr); + g_assert (!nle); + ++ /* IPv4 Broadcast address */ ++ if (family == AF_INET) { ++ struct in_addr bcast; ++ auto_nl_addr struct nl_addr *bcaddr = NULL; ++ ++ addr4_to_broadcast (&bcast, addr, plen); ++ bcaddr = nl_addr_build (family, &bcast, addrlen); ++ g_assert (bcaddr); ++ rtnl_addr_set_broadcast (rtnladdr, bcaddr); ++ } ++ ++ /* Peer/point-to-point address */ + if (peer_addr) { + auto_nl_addr struct nl_addr *nlpeer = nl_addr_build (family, peer_addr, addrlen); + + nle = rtnl_addr_set_peer (rtnladdr, nlpeer); + g_assert (!nle); + } + +-- +1.8.3.1 + diff --git a/rh1034921-startup-link-wait.patch b/rh1034921-startup-link-wait.patch new file mode 100644 index 0000000..d851b1f --- /dev/null +++ b/rh1034921-startup-link-wait.patch @@ -0,0 +1,833 @@ +From 07281f21a71fa333288821ad863accfeedfff567 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Mon, 9 Dec 2013 12:55:04 -0600 +Subject: [PATCH] core: delay startup complete until carrier is found or + timeout (rh #1034921) (rh #1030583) + +--- + src/devices/nm-device.c | 177 ++++++++++++++++++++++++++++++++++----------- + src/nm-active-connection.c | 8 ++ + 2 files changed, 142 insertions(+), 43 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index 578ccb0..96a5d44 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -184,15 +184,15 @@ typedef struct { + gboolean initialized; + gboolean in_state_changed; + + NMDeviceState state; + NMDeviceStateReason state_reason; + QueuedState queued_state; + guint queued_ip_config_id; +- guint pending_actions; ++ GArray *pending_actions; + + char * udi; + char * path; + char * iface; /* may change, could be renamed by user */ + int ifindex; + gboolean is_software; + char * ip_iface; +@@ -224,14 +224,15 @@ typedef struct { + gpointer act_source6_func; + + /* Link stuff */ + guint link_connected_id; + guint link_disconnected_id; + guint carrier_defer_id; + gboolean carrier; ++ guint carrier_wait_id; + gboolean ignore_carrier; + + /* Generic DHCP stuff */ + NMDHCPManager * dhcp_manager; + guint32 dhcp_timeout; + GByteArray * dhcp_anycast_address; + +@@ -390,14 +391,15 @@ nm_device_init (NMDevice *self) + priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; + priv->state = NM_DEVICE_STATE_UNMANAGED; + priv->state_reason = NM_DEVICE_STATE_REASON_NONE; + priv->dhcp_timeout = 0; + priv->rfkill_type = RFKILL_TYPE_UNKNOWN; + priv->autoconnect = DEFAULT_AUTOCONNECT; + priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); ++ priv->pending_actions = g_array_sized_new (FALSE, TRUE, sizeof (GQuark), 5); + } + + static void + update_accept_ra_save (NMDevice *self) + { + NMDevicePrivate *priv; + const char *ip_iface; +@@ -1154,14 +1156,20 @@ nm_device_set_carrier (NMDevice *device, gboolean carrier) + if (priv->carrier) { + nm_log_info (LOGD_DEVICE, "(%s): link connected", iface); + if (priv->carrier_defer_id) { + g_source_remove (priv->carrier_defer_id); + priv->carrier_defer_id = 0; + } + klass->carrier_changed (device, 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"); ++ } + } else if (state <= NM_DEVICE_STATE_DISCONNECTED) { + nm_log_info (LOGD_DEVICE, "(%s): link disconnected", iface); + klass->carrier_changed (device, FALSE); + } else { + nm_log_info (LOGD_DEVICE, "(%s): link disconnected (deferring action for %d seconds)", + iface, LINK_DISCONNECT_DELAY); + priv->carrier_defer_id = g_timeout_add_seconds (LINK_DISCONNECT_DELAY, +@@ -5110,17 +5118,28 @@ nm_device_start_ip_check (NMDevice *self) + /* If no ping was started, just advance to SECONDARIES */ + if (!priv->gw_ping.pid) + nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE); + } + + /****************************************************************/ + ++static gboolean ++carrier_wait_timeout (gpointer user_data) ++{ ++ NMDevice *self = NM_DEVICE (user_data); ++ ++ NM_DEVICE_GET_PRIVATE (self)->carrier_wait_id = 0; ++ nm_device_remove_pending_action (self, "carrier wait"); ++ return G_SOURCE_REMOVE; ++} ++ + gboolean + nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) + { ++ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean success; + guint32 tries = 0; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + if (nm_device_is_up (self)) + goto out; +@@ -5138,14 +5157,28 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) + g_usleep (200); + + if (!nm_device_is_up (self)) { + nm_log_warn (LOGD_HW, "(%s): device not up after timeout!", nm_device_get_iface (self)); + return FALSE; + } + ++ /* Devices that support carrier detect must be IFF_UP to report carrier ++ * changes; so after setting the device IFF_UP we must suppress startup ++ * complete (via a pending action) until either the carrier turns on, or ++ * a timeout is reached. ++ */ ++ if (device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { ++ if (priv->carrier_wait_id) { ++ g_source_remove (priv->carrier_wait_id); ++ nm_device_remove_pending_action (self, "carrier wait"); ++ } ++ priv->carrier_wait_id = g_timeout_add_seconds (5, carrier_wait_timeout, self); ++ nm_device_add_pending_action (self, "carrier wait"); ++ } ++ + out: + /* Can only get HW address of some devices when they are up */ + nm_device_update_hw_address (self); + + _update_ip4_address (self); + return TRUE; + } +@@ -5301,14 +5334,19 @@ dispose (GObject *object) + } + + if (priv->cp_updated_id) { + g_signal_handler_disconnect (priv->con_provider, priv->cp_updated_id); + priv->cp_updated_id = 0; + } + ++ if (priv->carrier_wait_id) { ++ g_source_remove (priv->carrier_wait_id); ++ priv->carrier_wait_id = 0; ++ } ++ + g_hash_table_unref (priv->available_connections); + priv->available_connections = NULL; + + activation_source_clear (self, TRUE, AF_INET); + activation_source_clear (self, TRUE, AF_INET6); + + clear_act_request (self); +@@ -5331,14 +5369,17 @@ finalize (GObject *object) + + if (priv->dhcp_manager) + g_object_unref (priv->dhcp_manager); + + if (priv->fw_manager) + g_object_unref (priv->fw_manager); + ++ g_array_free (priv->pending_actions, TRUE); ++ priv->pending_actions = NULL; ++ + g_free (priv->udi); + g_free (priv->path); + g_free (priv->iface); + g_free (priv->ip_iface); + g_free (priv->driver); + g_free (priv->driver_version); + g_free (priv->firmware_version); +@@ -5931,46 +5972,54 @@ nm_device_set_firmware_missing (NMDevice *self, gboolean new_missing) + + gboolean + nm_device_get_firmware_missing (NMDevice *self) + { + return NM_DEVICE_GET_PRIVATE (self)->firmware_missing; + } + ++#define QUEUED_PREFIX "queued state change to " ++ + static const char * +-state_to_string (NMDeviceState state) ++queued_state_to_string (NMDeviceState state) + { + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: +- return "unmanaged"; ++ return QUEUED_PREFIX "unmanaged"; + case NM_DEVICE_STATE_UNAVAILABLE: +- return "unavailable"; ++ return QUEUED_PREFIX "unavailable"; + case NM_DEVICE_STATE_DISCONNECTED: +- return "disconnected"; ++ return QUEUED_PREFIX "disconnected"; + case NM_DEVICE_STATE_PREPARE: +- return "prepare"; ++ return QUEUED_PREFIX "prepare"; + case NM_DEVICE_STATE_CONFIG: +- return "config"; ++ return QUEUED_PREFIX "config"; + case NM_DEVICE_STATE_NEED_AUTH: +- return "need-auth"; ++ return QUEUED_PREFIX "need-auth"; + case NM_DEVICE_STATE_IP_CONFIG: +- return "ip-config"; ++ return QUEUED_PREFIX "ip-config"; + case NM_DEVICE_STATE_IP_CHECK: +- return "ip-check"; ++ return QUEUED_PREFIX "ip-check"; + case NM_DEVICE_STATE_SECONDARIES: +- return "secondaries"; ++ return QUEUED_PREFIX "secondaries"; + case NM_DEVICE_STATE_ACTIVATED: +- return "activated"; ++ return QUEUED_PREFIX "activated"; + case NM_DEVICE_STATE_DEACTIVATING: +- return "deactivating"; ++ return QUEUED_PREFIX "deactivating"; + case NM_DEVICE_STATE_FAILED: +- return "failed"; ++ return QUEUED_PREFIX "failed"; + default: + break; + } +- return "unknown"; ++ return QUEUED_PREFIX "unknown"; ++} ++ ++static const char * ++state_to_string (NMDeviceState state) ++{ ++ return queued_state_to_string (state) + strlen (QUEUED_PREFIX); + } + + static const char * + reason_to_string (NMDeviceStateReason reason) + { + switch (reason) { + case NM_DEVICE_STATE_REASON_NONE: +@@ -6083,21 +6132,14 @@ reason_to_string (NMDeviceStateReason reason) + return "secondary-connection-failed"; + default: + break; + } + return "unknown"; + } + +-static inline gboolean +-state_implies_pending_action (NMDeviceState state) +-{ +- return ( state >= NM_DEVICE_STATE_PREPARE +- && state < NM_DEVICE_STATE_ACTIVATED); +-} +- + void + nm_device_state_changed (NMDevice *device, + NMDeviceState state, + NMDeviceStateReason reason) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + NMDeviceState old_state; +@@ -6131,18 +6173,14 @@ nm_device_state_changed (NMDevice *device, + return; + } + + old_state = priv->state; + priv->state = state; + priv->state_reason = reason; + +- if ( state_implies_pending_action (state) +- && !state_implies_pending_action (old_state)) +- nm_device_add_pending_action (device, "activation"); +- + 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, +@@ -6300,18 +6338,14 @@ nm_device_state_changed (NMDevice *device, + if (old_state == NM_DEVICE_STATE_ACTIVATED) + nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), device, NULL, NULL); + + /* Dispose of the cached activation request */ + if (req) + g_object_unref (req); + +- if ( state_implies_pending_action (old_state) +- && !state_implies_pending_action (state)) +- nm_device_remove_pending_action (device, "activation"); +- + priv->in_state_changed = FALSE; + } + + static gboolean + queued_set_state (gpointer user_data) + { + NMDevice *self = NM_DEVICE (user_data); +@@ -6330,15 +6364,15 @@ queued_set_state (gpointer user_data) + */ + priv->queued_state.id = 0; + new_state = priv->queued_state.state; + new_reason = priv->queued_state.reason; + nm_device_queued_state_clear (self); + + nm_device_state_changed (self, new_state, new_reason); +- nm_device_remove_pending_action (self, "queued state change"); ++ nm_device_remove_pending_action (self, queued_state_to_string (new_state)); + } else { + g_warn_if_fail (priv->queued_state.state == NM_DEVICE_STATE_UNKNOWN); + g_warn_if_fail (priv->queued_state.reason == NM_DEVICE_STATE_REASON_NONE); + } + return FALSE; + } + +@@ -6349,29 +6383,37 @@ nm_device_queue_state (NMDevice *self, + { + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + ++ /* "lock" the pending actions so that if there was a previously ++ * queued action that's about to be cleared, that doesn't drop ++ * the pending actions to 0 before we add the new pending action. ++ */ ++ nm_device_add_pending_action (self, "queued state lock"); ++ + /* We should only ever have one delayed state transition at a time */ + if (priv->queued_state.id) { + if (priv->queued_state.state == state) + return; + 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)); + nm_device_queued_state_clear (self); + } + + priv->queued_state.state = state; + priv->queued_state.reason = reason; + priv->queued_state.id = g_idle_add (queued_set_state, self); +- nm_device_add_pending_action (self, "queued state change"); ++ nm_device_add_pending_action (self, queued_state_to_string (state)); ++ ++ nm_device_remove_pending_action (self, "queued state lock"); + + 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); + } + + NMDeviceState +@@ -6391,15 +6433,15 @@ 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); + g_source_remove (priv->queued_state.id); +- nm_device_remove_pending_action (self, "queued state change"); ++ nm_device_remove_pending_action (self, queued_state_to_string (priv->queued_state.state)); + } + memset (&priv->queued_state, 0, sizeof (priv->queued_state)); + } + + NMDeviceState + nm_device_get_state (NMDevice *device) + { +@@ -7102,40 +7144,89 @@ nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, + } + nm_device_bring_up (device, TRUE, NULL); + g_free (mac_str); + + return success; + } + ++/** ++ * nm_device_add_pending_action(): ++ * @device: the #NMDevice to add the pending action to ++ * @action: a static string that identifies the action ++ * ++ * Adds a pending action to the device. ++ */ + void + nm_device_add_pending_action (NMDevice *device, const char *action) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); ++ GQuark qaction; ++ guint i; + +- priv->pending_actions++; +- nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): %s", +- nm_device_get_iface (device), priv->pending_actions, action); ++ qaction = g_quark_from_static_string (action); + +- if (priv->pending_actions == 1) ++ /* Shouldn't ever add the same pending action twice */ ++ for (i = 0; i < priv->pending_actions->len; i++) { ++ if (qaction == g_array_index (priv->pending_actions, GQuark, i)) { ++ nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already added", ++ nm_device_get_iface (device), ++ priv->pending_actions->len, ++ action); ++ g_warn_if_reached (); ++ return; ++ } ++ } ++ ++ g_array_prepend_val (priv->pending_actions, qaction); ++ nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s'", ++ nm_device_get_iface (device), ++ priv->pending_actions->len, ++ action); ++ ++ if (priv->pending_actions->len == 1) + g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + } + ++/** ++ * nm_device_remove_pending_action(): ++ * @device: the #NMDevice to remove the pending action from ++ * @action: a static string that identifies the action ++ * ++ * Removes a pending action previously added by nm_device_add_pending_action(). ++ */ + void + nm_device_remove_pending_action (NMDevice *device, const char *action) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); ++ GQuark qaction; ++ guint i; + +- priv->pending_actions--; +- nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): %s", +- nm_device_get_iface (device), priv->pending_actions, action); ++ qaction = g_quark_from_static_string (action); + +- if (priv->pending_actions == 0) +- g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); ++ /* Shouldn't ever add the same pending action twice */ ++ for (i = 0; i < priv->pending_actions->len; i++) { ++ if (qaction == g_array_index (priv->pending_actions, GQuark, i)) { ++ g_array_remove_index_fast (priv->pending_actions, i); ++ nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s'", ++ nm_device_get_iface (device), ++ priv->pending_actions->len, ++ action); ++ ++ if (priv->pending_actions->len == 0) ++ g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); ++ return; ++ } ++ } ++ ++ nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' never added", ++ nm_device_get_iface (device), ++ priv->pending_actions->len, ++ action); + } + + gboolean + nm_device_has_pending_action (NMDevice *device) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + +- return priv->pending_actions > 0; ++ return priv->pending_actions->len > 0; + } +diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c +index 6a825bc..34f438c 100644 +--- a/src/nm-active-connection.c ++++ b/src/nm-active-connection.c +@@ -135,14 +135,20 @@ nm_active_connection_set_state (NMActiveConnection *self, + + if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED + || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection), + (guint64) time (NULL), TRUE); + } + ++ if (priv->device) { ++ if ( old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED ++ && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) ++ nm_device_remove_pending_action (priv->device, "activation"); ++ } ++ + if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { + /* Device is no longer relevant when deactivated */ + g_clear_object (&priv->device); + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES); + } + } + +@@ -262,8 +268,10 @@ set_property (GObject *object, guint pro + case PROP_INT_DEVICE: + g_warn_if_fail (priv->device == NULL); + priv->device = g_value_dup_object (value); +- if (priv->device) ++ if (priv->device) { + g_warn_if_fail (priv->device != priv->master); ++ nm_device_add_pending_action (priv->device, "activation"); ++ } + break; + case PROP_INT_USER_REQUESTED: + priv->user_requested = g_value_get_boolean (value); +-- +1.8.3.1 + +From 813ea5995bb5a35c115c46f30eefe18db2886afb Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 16 Dec 2013 16:52:36 +0100 +Subject: [PATCH 1/2] core: allow dynamic strings for pending action names + +Use a GSList of the string values, instead of an array of GQuarks. +Using GQuarks does not allow to add arbitrary strings, because they +would leak the internalized strings. The next patch will begin +using unique, non-const action strings. + +Given the rather small number of expected pending states, a singly +linked list seems appropriate. + +Signed-off-by: Thomas Haller + +(some fixes and simplifications by dcbw based on patch reviews) +--- + src/devices/nm-device.c | 49 +++++++++++++++++++++++++------------------------ + 1 file changed, 25 insertions(+), 24 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index c1c7c69..e4644bf 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -184,15 +184,15 @@ typedef struct { + gboolean initialized; + gboolean in_state_changed; + + NMDeviceState state; + NMDeviceStateReason state_reason; + QueuedState queued_state; + guint queued_ip_config_id; +- GArray *pending_actions; ++ GSList *pending_actions; + + char * udi; + char * path; + char * iface; /* may change, could be renamed by user */ + int ifindex; + gboolean is_software; + char * ip_iface; +@@ -391,15 +391,14 @@ nm_device_init (NMDevice *self) + priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; + priv->state = NM_DEVICE_STATE_UNMANAGED; + priv->state_reason = NM_DEVICE_STATE_REASON_NONE; + priv->dhcp_timeout = 0; + priv->rfkill_type = RFKILL_TYPE_UNKNOWN; + priv->autoconnect = DEFAULT_AUTOCONNECT; + priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); +- priv->pending_actions = g_array_sized_new (FALSE, TRUE, sizeof (GQuark), 5); + } + + static void + update_accept_ra_save (NMDevice *self) + { + NMDevicePrivate *priv; + const char *ip_iface; +@@ -5368,16 +5367,15 @@ finalize (GObject *object) + + if (priv->dhcp_manager) + g_object_unref (priv->dhcp_manager); + + if (priv->fw_manager) + g_object_unref (priv->fw_manager); + +- g_array_free (priv->pending_actions, TRUE); +- priv->pending_actions = NULL; ++ g_slist_free_full (priv->pending_actions, g_free); + + g_free (priv->udi); + g_free (priv->path); + g_free (priv->iface); + g_free (priv->ip_iface); + g_free (priv->driver); + g_free (priv->driver_version); +@@ -7153,78 +7152,80 @@ nm_device_set_hw_addr (NMDevice *device, const guint8 *addr, + * + * Adds a pending action to the device. + */ + void + nm_device_add_pending_action (NMDevice *device, const char *action) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); +- GQuark qaction; +- guint i; ++ GSList *iter; ++ guint count; + +- qaction = g_quark_from_static_string (action); ++ g_return_if_fail (action); + + /* Shouldn't ever add the same pending action twice */ +- for (i = 0; i < priv->pending_actions->len; i++) { +- if (qaction == g_array_index (priv->pending_actions, GQuark, i)) { ++ for (iter = priv->pending_actions; iter; iter = iter->next) { ++ if (!strcmp (action, iter->data)) { + nm_log_warn (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s' already added", + nm_device_get_iface (device), +- priv->pending_actions->len, ++ g_slist_length (priv->pending_actions), + action); +- g_warn_if_reached (); +- return; ++ g_return_val_if_reached (FALSE); + } + } + +- g_array_prepend_val (priv->pending_actions, qaction); ++ priv->pending_actions = g_slist_append (priv->pending_actions, g_strdup (action)); ++ count = g_slist_length (priv->pending_actions); ++ + nm_log_dbg (LOGD_DEVICE, "(%s): add_pending_action (%d): '%s'", + nm_device_get_iface (device), +- priv->pending_actions->len, ++ count, + action); + +- if (priv->pending_actions->len == 1) ++ if (count == 1) + g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + } + + /** + * nm_device_remove_pending_action(): + * @device: the #NMDevice to remove the pending action from + * @action: a static string that identifies the action + * + * Removes a pending action previously added by nm_device_add_pending_action(). + */ + void + nm_device_remove_pending_action (NMDevice *device, const char *action) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); +- GQuark qaction; +- guint i; ++ GSList *iter; + +- qaction = g_quark_from_static_string (action); ++ g_return_if_fail (action); + + /* Shouldn't ever add the same pending action twice */ +- for (i = 0; i < priv->pending_actions->len; i++) { +- if (qaction == g_array_index (priv->pending_actions, GQuark, i)) { +- g_array_remove_index_fast (priv->pending_actions, i); ++ for (iter = priv->pending_actions; iter; iter = iter->next) { ++ if (!strcmp (action, iter->data)) { ++ g_free (iter->data); ++ priv->pending_actions = g_slist_delete_link (priv->pending_actions, iter); + nm_log_dbg (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s'", + nm_device_get_iface (device), +- priv->pending_actions->len, ++ g_slist_length (priv->pending_actions), + action); + +- if (priv->pending_actions->len == 0) ++ if (priv->pending_actions == NULL) + g_object_notify (G_OBJECT (device), NM_DEVICE_HAS_PENDING_ACTION); + return; + } + } + + nm_log_warn (LOGD_DEVICE, "(%s): remove_pending_action (%d): '%s' never added", + nm_device_get_iface (device), +- priv->pending_actions->len, ++ g_slist_length (priv->pending_actions), + action); ++ g_return_if_reached (); + } + + gboolean + nm_device_has_pending_action (NMDevice *device) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + +- return priv->pending_actions->len > 0; ++ return !!priv->pending_actions; + } +-- +1.8.3.1 + +From b6ef165cfefba44a496cc336e1f91bb93b28f3ff Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Mon, 16 Dec 2013 15:02:38 +0100 +Subject: [PATCH 2/2] core: fix NMActiveConnection to properly add/remove + pending action "activation" + +When a new activation request is received, NetworkManager creates a new +NMActiveConnection to track that request. The device may already be activated, +in which case NetworkManager stops the old activation and starts the new one, +but both exist in parallel for a short period of time. If the old +NMActiveConnection is activating and already has a pending 'activation' +action, when the new NMActiveConnection adds its own 'activating' action, +they will clash. This is fixed by making each NMActiveConnection's activation +pending action uniquely named. + +This fixes a g_warning with the following back trace: + + #0 0x000000328224edfd in g_logv () from /lib64/libglib-2.0.so.0 + #1 0x000000328224efe2 in g_log () from /lib64/libglib-2.0.so.0 + #2 0x000000328224f2e6 in g_warn_message () from /lib64/libglib-2.0.so.0 + #3 0x0000000000440aee in nm_device_add_pending_action (device=0x14002e0, action=0x50704a "activation") at devices/nm-device.c:7172 + #4 0x000000000047525c in nm_active_connection_set_device (self=0x141b3c0, device=0x14002e0) at nm-active-connection.c:364 + #5 0x0000000000475ec1 in set_property (object=0x141b3c0, prop_id=11, value=0x7fff7ff36c20, pspec=0x1405f70) at nm-active-connection.c:647 + #6 0x0000003282615d3e in g_object_newv () from /lib64/libgobject-2.0.so.0 + #7 0x00000032826162e6 in g_object_new_valist () from /lib64/libgobject-2.0.so.0 + #8 0x0000003282616654 in g_object_new () from /lib64/libgobject-2.0.so.0 + #9 0x0000000000474193 in nm_act_request_new (connection=0x13bb0e0, specific_object=0x0, subject=0x1447740, device=0x14002e0) at nm-activation-request.c:376 + #10 0x000000000048e477 in _new_active_connection (self=0x13e8060, connection=0x13bb0e0, specific_object=0x0, device=0x14002e0, subject=0x1447740, error=0x7fff7ff36f90) at nm-manager.c:2947 + #11 0x000000000048ed77 in impl_manager_activate_connection (self=0x13e8060, connection_path=0x134d590 "/org/freedesktop/NetworkManager/Settings/9", device_path=0x134d550 "/org/freedesktop/NetworkManager/Devices/1", + specific_object_path=0x0, context=0x143a9b0) at nm-manager.c:3206 + #12 0x00000000004876c8 in dbus_glib_marshal_nm_manager_VOID__BOXED_BOXED_BOXED_POINTER (closure=0x7fff7ff37220, return_value=0x0, n_param_values=5, param_values=0x1448830, invocation_hint=0x0, + marshal_data=0x48e9dd ) at nm-manager-glue.h:189 + #13 0x0000003284a0d6a9 in object_registration_message () from /lib64/libdbus-glib-1.so.2 + #14 0x000000348ea1ce66 in _dbus_object_tree_dispatch_and_unlock () from /lib64/libdbus-1.so.3 + #15 0x000000348ea0fa31 in dbus_connection_dispatch () from /lib64/libdbus-1.so.3 + #16 0x0000003284a0acc5 in message_queue_dispatch () from /lib64/libdbus-glib-1.so.2 + #17 0x0000003282247df6 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0 + #18 0x0000003282248148 in g_main_context_iterate.isra.22 () from /lib64/libglib-2.0.so.0 + #19 0x000000328224854a in g_main_loop_run () from /lib64/libglib-2.0.so.0 + #20 0x000000000042c6c0 in main (argc=1, argv=0x7fff7ff379b8) at main.c:629 + +Signed-off-by: Thomas Haller +--- + src/nm-active-connection.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c +index cb42417..a8a422c 100644 +--- a/src/nm-active-connection.c ++++ b/src/nm-active-connection.c +@@ -42,14 +42,16 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, G_TYPE_OBJECT) + NMDevice *device; + + gboolean is_default; + gboolean is_default6; + NMActiveConnectionState state; + gboolean vpn; + ++ char *pending_activation_id; ++ + gboolean user_requested; + gulong user_uid; + NMDevice *master; + } NMActiveConnectionPrivate; + + enum { + PROP_0, +@@ -138,16 +140,20 @@ nm_active_connection_set_state (NMActiveConnection *self, + || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { + nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection), + (guint64) time (NULL), TRUE); + } + + if (priv->device) { + if ( old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED +- && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) +- nm_device_remove_pending_action (priv->device, "activation"); ++ && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED && ++ priv->pending_activation_id) ++ { ++ nm_device_remove_pending_action (priv->device, priv->pending_activation_id); ++ g_clear_pointer (&priv->pending_activation_id, g_free); ++ } + } + + if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { + /* Device is no longer relevant when deactivated */ + g_clear_object (&priv->device); + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEVICES); + } +@@ -357,15 +363,16 @@ set_property (GObject *object, guint prop_id, + priv->connection = g_value_dup_object (value); + break; + case PROP_INT_DEVICE: + g_warn_if_fail (priv->device == NULL); + priv->device = g_value_dup_object (value); + if (priv->device) { + g_warn_if_fail (priv->device != priv->master); +- nm_device_add_pending_action (priv->device, "activation"); ++ priv->pending_activation_id = g_strdup_printf ("activation::%p", (void *)object); ++ nm_device_add_pending_action (priv->device, priv->pending_activation_id); + } + break; + case PROP_INT_USER_REQUESTED: + priv->user_requested = g_value_get_boolean (value); + break; + case PROP_INT_USER_UID: + priv->user_uid = g_value_get_ulong (value); +@@ -732,14 +739,18 @@ static void + + g_free (priv->path); + priv->path = NULL; + g_free (priv->specific_object); + priv->specific_object = NULL; + + g_clear_object (&priv->connection); ++ if (priv->pending_activation_id) { ++ nm_device_remove_pending_action (priv->device, priv->pending_activation_id); ++ g_clear_pointer (&priv->pending_activation_id, g_free); ++ } + g_clear_object (&priv->device); + g_clear_object (&priv->master); + + G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); + } + + static void +-- +1.8.3.1 + From 2af4e12ad1dc66a8343a0649bbfe2491b9932071 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 19 Dec 2013 18:07:36 -0600 Subject: [PATCH 14/15] core: fix IPv6 router solicitation loop (rh #1044757) --- NetworkManager.spec | 7 +- rh1044757-ipv6-solicit-infinity.patch | 431 ++++++++++++++++++++++++++ 2 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 rh1044757-ipv6-solicit-infinity.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index 001c6e9..c4c1d8c 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 21%{snapshot}%{?dist} +Release: 22%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -48,6 +48,7 @@ Patch18: rh1018317-openvpn-ptp.patch Patch19: rh1034921-startup-link-wait.patch Patch20: rh1029213-ignore-RA-default-routes.patch Patch21: rh1032819-set-broadcast-address.patch +Patch22: rh1044757-ipv6-solicit-infinity.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -192,6 +193,7 @@ deployments. %patch19 -p1 -b .startup-linkwait %patch20 -p1 -b .ignore-RA-default-routes %patch21 -p1 -b .broadcast-addr +%patch22 -p1 -b .ipv6-solicit-infinity %build @@ -390,6 +392,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Thu Dec 19 2013 Dan Williams - 0.9.9.0-22.git20131003 +- core: fix IPv6 router solicitation loop (rh #1044757) + * Thu Dec 12 2013 Dan Williams - 0.9.9.0-21.git20131003 - core: wait for link before declaring startup complete (rh #1034921) - core: ignore RA-provided IPv6 default routes (rh #1029213) diff --git a/rh1044757-ipv6-solicit-infinity.patch b/rh1044757-ipv6-solicit-infinity.patch new file mode 100644 index 0000000..818a714 --- /dev/null +++ b/rh1044757-ipv6-solicit-infinity.patch @@ -0,0 +1,431 @@ +From 8d3618a07baccc8abd9cfe7cf5b000b5d8c3340b Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Wed, 23 Oct 2013 18:37:02 +0200 +Subject: [PATCH] rdisc: emit config_change signal for update of address + lifetime + +Signed-off-by: Thomas Haller +--- + src/rdisc/nm-lndp-rdisc.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c +index 3299b32..f94d82a 100644 +--- a/src/rdisc/nm-lndp-rdisc.c ++++ b/src/rdisc/nm-lndp-rdisc.c +@@ -101,16 +101,19 @@ add_address (NMRDisc *rdisc, const NMRDiscAddress *new) + { + int i; + + for (i = 0; i < rdisc->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); + + if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { +- memcpy (item, new, sizeof (*new)); +- return FALSE; ++ gboolean changed = item->timestamp + item->lifetime != new->timestamp + new->lifetime || ++ item->timestamp + item->preferred != new->timestamp + new->preferred; ++ ++ *item = *new; ++ return changed; + } + } + + g_array_insert_val (rdisc->addresses, i, *new); + return TRUE; + } + +-- +1.8.3.1 + +From 4f3f789fa5dad459a2aecabd77ef4a595dec5013 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 19 Dec 2013 10:58:46 -0600 +Subject: [PATCH] rdisc: ensure RDNSS and DNSSL lifetimes are updated (rh + #1044757) (bgo #720760) + +The DNS server and domain timestamps and lifetimes weren't updated +when a new RA was received. When half the lifetime for either of +them had passed, clean_dns_servers() and clean_domains() request a +Router Solicitation to ensure the DNS information does not expire. + +This obviously results in a new Router Advertisement, but since the +timestamps don't get updated, clean_dns_servers() and clean_domains() +simply request another solicitation because 'now' is still greater +than half the old lifetime. This casues another solicit request, +which causes another RA, which... etc. + +https://bugzilla.redhat.com/show_bug.cgi?id=1044757 +https://bugzilla.gnome.org/show_bug.cgi?id=720760 +--- + src/devices/nm-device.c | 9 +++-- + src/rdisc/nm-lndp-rdisc.c | 97 +++++++++++++++++++++++++++++------------------ + 2 files changed, 67 insertions(+), 39 deletions(-) + +diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c +index 74d443d..6f2383b 100644 +--- a/src/devices/nm-device.c ++++ b/src/devices/nm-device.c +@@ -3315,14 +3315,17 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device + NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + + nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address); + } + } + + if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) { ++ /* Rebuild domain list from router discovery cache. */ ++ nm_ip6_config_reset_domains (priv->ac_ip6_config); ++ + for (i = 0; i < rdisc->dns_domains->len; i++) { + NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + + nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain); + } + } + +@@ -3357,28 +3360,29 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device + + static gboolean + addrconf6_start (NMDevice *self) + { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMConnection *connection; ++ const char *ip_iface = nm_device_get_ip_iface (self); + + connection = nm_device_get_connection (self); + g_assert (connection); + + g_warn_if_fail (priv->ac_ip6_config == NULL); + if (priv->ac_ip6_config) { + g_object_unref (priv->ac_ip6_config); + priv->ac_ip6_config = NULL; + } + +- priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), nm_device_get_ip_iface (self)); ++ priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface); + nm_platform_sysctl_set (priv->ip6_accept_ra_path, "0"); + + if (!priv->rdisc) { +- nm_log_err (LOGD_IP6, "Failed to start router discovery."); ++ nm_log_err (LOGD_IP6, "(%s): failed to start router discovery.", ip_iface); + return FALSE; + } + + priv->rdisc_config_changed_sigid = g_signal_connect ( + priv->rdisc, NM_RDISC_CONFIG_CHANGED, G_CALLBACK (rdisc_config_changed), self); + + /* FIXME: what if interface has no lladdr, like PPP? */ +diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c +index f94d82a..2e22fd9 100644 +--- a/src/rdisc/nm-lndp-rdisc.c ++++ b/src/rdisc/nm-lndp-rdisc.c +@@ -140,44 +140,68 @@ add_route (NMRDisc *rdisc, const NMRDiscRoute *new) + } + + g_array_insert_val (rdisc->routes, i, *new); + return TRUE; + } + + static gboolean +-add_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) ++add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) + { + int i; + + for (i = 0; i < rdisc->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); + +- if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) +- return FALSE; ++ if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { ++ gboolean changed = item->timestamp != new->timestamp || ++ item->lifetime != new->lifetime; ++ if (changed) { ++ item->timestamp = new->timestamp; ++ item->lifetime = new->lifetime; ++ } ++ return changed; ++ } + } + ++ /* DNS server should no longer be used */ ++ if (new->lifetime == 0) ++ return FALSE; ++ + g_array_insert_val (rdisc->dns_servers, i, *new); +- + return TRUE; + } + ++/* Always copies new->domain */ + static gboolean + add_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) + { ++ NMRDiscDNSDomain *item; + int i; + + for (i = 0; i < rdisc->dns_domains->len; i++) { +- NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); ++ item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); + +- if (!g_strcmp0 (item->domain, new->domain)) +- return FALSE; ++ if (!g_strcmp0 (item->domain, new->domain)) { ++ gboolean changed = item->timestamp != new->timestamp || ++ item->lifetime != new->lifetime; ++ if (changed) { ++ item->timestamp = new->timestamp; ++ item->lifetime = new->lifetime; ++ } ++ return changed; ++ } + } + ++ /* 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); + return TRUE; + } + + #define RETRY 10 + + static gboolean + send_rs (NMRDisc *rdisc) +@@ -186,15 +210,15 @@ send_rs (NMRDisc *rdisc) + struct ndp_msg *msg; + int error; + + error = ndp_msg_new (&msg, NDP_MSG_RS); + g_assert (!error); + ndp_msg_ifindex_set (msg, rdisc->ifindex); + +- debug ("(%s): sending router solicitation: %d", rdisc->ifname, rdisc->ifindex); ++ debug ("(%s): sending router solicitation", rdisc->ifname); + + error = ndp_msg_send (priv->ndp, msg); + if (error) + error ("(%s): cannot send router solicitation: %d.", rdisc->ifname, error); + + ndp_msg_destroy (msg); + +@@ -218,139 +242,140 @@ solicit (NMRDisc *rdisc) + static void + clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) + { + int i; + + for (i = 0; i < rdisc->gateways->len; i++) { + NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i); +- guint32 expiry = item->timestamp + item->lifetime; ++ guint64 expiry = item->timestamp + item->lifetime; + +- if (item->lifetime == UINT_MAX) ++ if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->gateways, i--); + *changed |= NM_RDISC_CONFIG_GATEWAYS; + } else if (*nextevent > expiry) +- *nextevent = expiry; ++ *nextevent = (guint32) expiry; + } + } + + static void + clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) + { + int i; + + for (i = 0; i < rdisc->addresses->len; i++) { + NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i); +- guint32 expiry = item->timestamp + item->lifetime; ++ guint64 expiry = item->timestamp + item->lifetime; + +- if (item->lifetime == UINT_MAX) ++ if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->addresses, i--); + *changed |= NM_RDISC_CONFIG_ADDRESSES; + } else if (*nextevent > expiry) +- *nextevent = expiry; ++ *nextevent = (guint32) expiry; + } + } + + static void + clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) + { + int i; + + for (i = 0; i < rdisc->routes->len; i++) { + NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i); +- guint32 expiry = item->timestamp + item->lifetime; ++ guint64 expiry = item->timestamp + item->lifetime; + +- if (item->lifetime == UINT_MAX) ++ if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->routes, i--); + *changed |= NM_RDISC_CONFIG_ROUTES; + } else if (*nextevent > expiry) +- *nextevent = expiry; ++ *nextevent = (guint32) expiry; + } + } + + static void +-clean_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) ++clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) + { + int i; + + for (i = 0; i < rdisc->dns_servers->len; i++) { + NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i); +- guint32 expiry = item->timestamp + item->lifetime; +- guint32 refresh = item->timestamp + item->lifetime / 2; ++ guint64 expiry = item->timestamp + item->lifetime; ++ guint64 refresh = item->timestamp + item->lifetime / 2; + +- if (item->lifetime == UINT_MAX) ++ if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { + g_array_remove_index (rdisc->dns_servers, i--); +- *changed |= NM_RDISC_CONFIG_ROUTES; ++ *changed |= NM_RDISC_CONFIG_DNS_SERVERS; + } else if (now >= refresh) + solicit (rdisc); + else if (*nextevent > refresh) +- *nextevent = refresh; ++ *nextevent = (guint32) refresh; + } + } + + static void + clean_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) + { + int i; + + for (i = 0; i < rdisc->dns_domains->len; i++) { + NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i); +- guint32 expiry = item->timestamp + item->lifetime; +- guint32 refresh = item->timestamp + item->lifetime / 2; ++ guint64 expiry = item->timestamp + item->lifetime; ++ guint64 refresh = item->timestamp + item->lifetime / 2; + +- if (item->lifetime == UINT_MAX) ++ if (item->lifetime == G_MAXUINT32) + continue; + + if (now >= expiry) { ++ g_free (item->domain); + g_array_remove_index (rdisc->dns_domains, i--); +- *changed |= NM_RDISC_CONFIG_ROUTES; ++ *changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + } else if (now >= refresh) + solicit (rdisc); + else if (*nextevent >=refresh) +- *nextevent = refresh; ++ *nextevent = (guint32) refresh; + } + } + + static gboolean timeout_cb (gpointer user_data); + + static void + check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) + { + NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); +- /* Use a magic date in distant enough future as there's no guint32 max macro. */ +- guint32 never = G_MAXINT32; ++ /* Use a magic date in the distant future (~68 years) */ ++ guint32 never = G_MAXINT32; + guint32 nextevent = never; + + if (priv->timeout_id) { + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; + } + + clean_gateways (rdisc, now, &changed, &nextevent); + clean_addresses (rdisc, now, &changed, &nextevent); + clean_routes (rdisc, now, &changed, &nextevent); +- clean_servers (rdisc, now, &changed, &nextevent); ++ clean_dns_servers (rdisc, now, &changed, &nextevent); + clean_domains (rdisc, now, &changed, &nextevent); + + if (changed) + g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, changed); + + if (nextevent != never) { +- debug ("Scheduling next now/lifetime check: %d seconds", (int) nextevent); ++ debug ("(%s): scheduling next now/lifetime check: %u seconds", rdisc->ifname, nextevent); + priv->timeout_id = g_timeout_add_seconds (nextevent, timeout_cb, rdisc); + } + } + + static guint32 + get_time (void) + { +@@ -450,15 +475,15 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) + * + * The biggest difference from good old DHCP is that all configuration + * items have their own lifetimes and they are merged from various + * sources. Router discovery is *not* contract-based, so there is *no* + * single time when the configuration is finished and updates can + * come at any time. + */ +- debug ("Recieved router advertisement: %d at %d", rdisc->ifindex, (int) now); ++ 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; + } + + /* DHCP level: +@@ -559,27 +584,27 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) + /* Pad the lifetime somewhat to give a bit of slack in cases + * where one RA gets lost or something (which can happen on unreliable + * links like WiFi where certain types of frames are not retransmitted). + * Note that 0 has special meaning and is therefore not adjusted. + */ + if (dns_server.lifetime && dns_server.lifetime < 7200) + dns_server.lifetime = 7200; +- if (add_server (rdisc, &dns_server)) ++ if (add_dns_server (rdisc, &dns_server)) + changed |= NM_RDISC_CONFIG_DNS_SERVERS; + } + } + ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_DNSSL) { + char *domain; + int domain_index; + + ndp_msg_opt_dnssl_for_each_domain (domain, domain_index, msg, offset) { + NMRDiscDNSDomain dns_domain; + + memset (&dns_domain, 0, sizeof (dns_domain)); +- dns_domain.domain = g_strdup (domain); ++ dns_domain.domain = domain; + dns_domain.timestamp = now; + dns_domain.lifetime = ndp_msg_opt_rdnss_lifetime (msg, offset); + /* Pad the lifetime somewhat to give a bit of slack in cases + * where one RA gets lost or something (which can happen on unreliable + * links like WiFi where certain types of frames are not retransmitted). + * Note that 0 has special meaning and is therefore not adjusted. + */ +-- +1.8.3.1 + From d9c5764ddb7a90f57a3d13b542bafada9beb6d92 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 6 Jan 2014 12:12:29 -0500 Subject: [PATCH 15/15] bluez-manager: fix a crash (rh #1048711) --- NetworkManager.spec | 7 ++++++- rh1048711-bluez-crash.patch | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 rh1048711-bluez-crash.patch diff --git a/NetworkManager.spec b/NetworkManager.spec index c4c1d8c..c6df96f 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -19,7 +19,7 @@ Name: NetworkManager Summary: Network connection manager and user applications Epoch: 1 Version: 0.9.9.0 -Release: 22%{snapshot}%{?dist} +Release: 23%{snapshot}%{?dist} Group: System Environment/Base License: GPLv2+ URL: http://www.gnome.org/projects/NetworkManager/ @@ -49,6 +49,7 @@ Patch19: rh1034921-startup-link-wait.patch Patch20: rh1029213-ignore-RA-default-routes.patch Patch21: rh1032819-set-broadcast-address.patch Patch22: rh1044757-ipv6-solicit-infinity.patch +Patch23: rh1048711-bluez-crash.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -194,6 +195,7 @@ deployments. %patch20 -p1 -b .ignore-RA-default-routes %patch21 -p1 -b .broadcast-addr %patch22 -p1 -b .ipv6-solicit-infinity +%patch23 -p1 -b .bluez-crash %build @@ -392,6 +394,9 @@ fi %config %{_sysconfdir}/%{name}/conf.d/00-server.conf %changelog +* Mon Jan 6 2014 Dan Winship - 0.9.9.0-23.git20131003 +- bluez-manager: fix a crash (rh #1048711) + * Thu Dec 19 2013 Dan Williams - 0.9.9.0-22.git20131003 - core: fix IPv6 router solicitation loop (rh #1044757) diff --git a/rh1048711-bluez-crash.patch b/rh1048711-bluez-crash.patch new file mode 100644 index 0000000..f8b7457 --- /dev/null +++ b/rh1048711-bluez-crash.patch @@ -0,0 +1,21 @@ +diff -up NetworkManager-0.9.9.0/src/bluez-manager/nm-bluez-device.c.bluez-crash NetworkManager-0.9.9.0/src/bluez-manager/nm-bluez-device.c +--- NetworkManager-0.9.9.0/src/bluez-manager/nm-bluez-device.c.bluez-crash 2013-10-03 15:00:51.000000000 -0400 ++++ NetworkManager-0.9.9.0/src/bluez-manager/nm-bluez-device.c 2014-01-06 12:09:14.449583005 -0500 +@@ -686,7 +686,7 @@ static void + on_adapter_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) + { + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); +- GError *error; ++ GError *error = NULL; + GVariant *v; + + priv->adapter = g_dbus_proxy_new_for_bus_finish (res, &error); +@@ -923,7 +923,7 @@ static void + on_proxy_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) + { + NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); +- GError *error; ++ GError *error = NULL; + + priv->proxy5 = g_dbus_proxy_new_for_bus_finish (res, &error); +