Fix various problems
- core: fix reading physical port id for sysfs - libnm-glib: export get_gateway() and get_searches() functions - libnm-glib: new functions for bindings to get nameservers - libnm-glib: chain up the parent constructed() of NMRemoteConnection - core: exit cleanly if D-Bus cannot be initialized (rh #1057738) - dhcp: don't add an IPv6 address if one wasn't given (rh #1048046) - core: Add host route for DHCP4 server if outside assigned subnet (bgo #721767) (rh #983325) - vpn: handle missing tunnel interface for IP-based VPNs (bgo #721724) (rh #1030068) (rh #865883) - core: only log about IPv6 Commit the first time (rh #1044757)
This commit is contained in:
parent
d112c5a56c
commit
25f86691e2
|
@ -19,7 +19,7 @@ Name: NetworkManager
|
||||||
Summary: Network connection manager and user applications
|
Summary: Network connection manager and user applications
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 0.9.9.0
|
Version: 0.9.9.0
|
||||||
Release: 26%{snapshot}%{?dist}
|
Release: 27%{snapshot}%{?dist}
|
||||||
Group: System Environment/Base
|
Group: System Environment/Base
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://www.gnome.org/projects/NetworkManager/
|
URL: http://www.gnome.org/projects/NetworkManager/
|
||||||
|
@ -56,6 +56,16 @@ Patch26: rh1036132-VPN-active-con-info.patch
|
||||||
Patch27: rh1031574-primary-connection.patch
|
Patch27: rh1031574-primary-connection.patch
|
||||||
Patch28: physical-port-id.patch
|
Patch28: physical-port-id.patch
|
||||||
Patch29: gi-fix-for-ipv6.patch
|
Patch29: gi-fix-for-ipv6.patch
|
||||||
|
Patch30: fix-read-phys-port-id.patch
|
||||||
|
Patch31: export-missing-libnm-glib-funcs.patch
|
||||||
|
Patch32: get-nameservers.patch
|
||||||
|
Patch33: get-ip-examples.patch
|
||||||
|
Patch34: rem-con-constructed.patch
|
||||||
|
Patch35: rh1057738-dbus-clean-exit.patch
|
||||||
|
Patch36: rh1048046-dhcp-no-ipv6.patch
|
||||||
|
Patch37: rh983325-add-route-for-dhcp-server.patch
|
||||||
|
Patch38: rh1030068-vpn-tunnel-interface.patch
|
||||||
|
Patch39: core-log-ipv6-commit.patch
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
|
@ -208,6 +218,16 @@ deployments.
|
||||||
%patch27 -p1 -b .primary-connection
|
%patch27 -p1 -b .primary-connection
|
||||||
%patch28 -p1 -b .physical-port-id
|
%patch28 -p1 -b .physical-port-id
|
||||||
%patch29 -p1 -b .gi-fix-for-ipv6
|
%patch29 -p1 -b .gi-fix-for-ipv6
|
||||||
|
%patch30 -p1 -b .fix-read-phys-port-id
|
||||||
|
%patch31 -p1 -b .export-missing-libnm-glib-funcs
|
||||||
|
%patch32 -p1 -b .get-nameservers
|
||||||
|
%patch33 -p1 -b .get-ip-examples
|
||||||
|
%patch34 -p1 -b .rem-con-constructed
|
||||||
|
%patch35 -p1 -b .rh1057738-dbus-clean-exit
|
||||||
|
%patch36 -p1 -b .rh1048046-dhcp-no-ipv6
|
||||||
|
%patch37 -p1 -b .rh983325-add-route-for-dhcp-server
|
||||||
|
%patch38 -p1 -b .rh1030068-vpn-tunnel-interface
|
||||||
|
%patch39 -p1 -b .core-log-ipv6-commit
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
|
||||||
|
@ -406,6 +426,17 @@ fi
|
||||||
%config %{_sysconfdir}/%{name}/conf.d/00-server.conf
|
%config %{_sysconfdir}/%{name}/conf.d/00-server.conf
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 28 2014 Jiří Klimeš <jklimes@redhat.com> - 0.9.9.0-27.git20131003
|
||||||
|
- core: fix reading physical port id for sysfs
|
||||||
|
- libnm-glib: export get_gateway() and get_searches() functions
|
||||||
|
- libnm-glib: new functions for bindings to get nameservers
|
||||||
|
- libnm-glib: chain up the parent constructed() of NMRemoteConnection
|
||||||
|
- core: exit cleanly if D-Bus cannot be initialized (rh #1057738)
|
||||||
|
- dhcp: don't add an IPv6 address if one wasn't given (rh #1048046)
|
||||||
|
- core: Add host route for DHCP4 server if outside assigned subnet (bgo #721767) (rh #983325)
|
||||||
|
- vpn: handle missing tunnel interface for IP-based VPNs (bgo #721724) (rh #1030068) (rh #865883)
|
||||||
|
- core: only log about IPv6 Commit the first time (rh #1044757)
|
||||||
|
|
||||||
* Tue Jan 21 2014 Jiří Klimeš <jklimes@redhat.com> - 0.9.9.0-26.git20131003
|
* Tue Jan 21 2014 Jiří Klimeš <jklimes@redhat.com> - 0.9.9.0-26.git20131003
|
||||||
- core: improve handling of NPAR/SR-IOV devices (rh #804527)
|
- core: improve handling of NPAR/SR-IOV devices (rh #804527)
|
||||||
- libnm-glib: add NMDevice:physical-port-id property
|
- libnm-glib: add NMDevice:physical-port-id property
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
From 13f4a00d4d490fb65f93c246d1c93ed56a47213f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dan Williams <dcbw@redhat.com>
|
||||||
|
Date: Thu, 23 Jan 2014 13:02:16 -0600
|
||||||
|
Subject: [PATCH] core: only log about IPv6 Commit the first time
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Since IPv6 configuration gets updated every time a router advertisement
|
||||||
|
comes in, it can lead NM to continuously logging:
|
||||||
|
|
||||||
|
NetworkManager: <info> Activation (eth0) Stage 5 of 5 (IPv6 Commit) scheduled...
|
||||||
|
NetworkManager: <info> Activation (eth0) Stage 5 of 5 (IPv6 Commit) started...
|
||||||
|
NetworkManager: <info> Activation (eth0) Stage 5 of 5 (IPv6 Commit) complete.
|
||||||
|
|
||||||
|
that's annoying. So after the initial configuration is done, make
|
||||||
|
subsequent IPv6 Commit log messages debug instead of info.
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/devices/nm-device.c | 20 ++++++++++----------
|
||||||
|
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
|
||||||
|
index 035434e..4684efe 100644
|
||||||
|
--- a/src/devices/nm-device.c
|
||||||
|
+++ b/src/devices/nm-device.c
|
||||||
|
@@ -335,8 +335,6 @@ static gboolean nm_device_set_ip6_config (NMDevice *dev,
|
||||||
|
gboolean commit,
|
||||||
|
NMDeviceStateReason *reason);
|
||||||
|
|
||||||
|
-static gboolean nm_device_activate_ip6_config_commit (gpointer user_data);
|
||||||
|
-
|
||||||
|
static gboolean check_connection_available (NMDevice *device, NMConnection *connection);
|
||||||
|
|
||||||
|
static gboolean spec_match_list (NMDevice *device, const GSList *specs);
|
||||||
|
@@ -4232,6 +4230,7 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
|
||||||
|
{
|
||||||
|
NMDevice *self = NM_DEVICE (user_data);
|
||||||
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
+ guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO;
|
||||||
|
NMActRequest *req;
|
||||||
|
const char *iface;
|
||||||
|
NMConnection *connection;
|
||||||
|
@@ -4241,8 +4240,7 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
|
||||||
|
activation_source_clear (self, FALSE, AF_INET6);
|
||||||
|
|
||||||
|
iface = nm_device_get_iface (self);
|
||||||
|
- nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv6 Commit) started...",
|
||||||
|
- iface);
|
||||||
|
+ nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) started...", iface);
|
||||||
|
|
||||||
|
req = nm_device_get_act_request (self);
|
||||||
|
g_assert (req);
|
||||||
|
@@ -4262,14 +4260,13 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
|
||||||
|
if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
|
||||||
|
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
|
||||||
|
} else {
|
||||||
|
- nm_log_info (LOGD_DEVICE | LOGD_IP6,
|
||||||
|
+ nm_log_warn (LOGD_DEVICE | LOGD_IP6,
|
||||||
|
"Activation (%s) Stage 5 of 5 (IPv6 Commit) failed",
|
||||||
|
iface);
|
||||||
|
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
- nm_log_info (LOGD_DEVICE, "Activation (%s) Stage 5 of 5 (IPv6 Commit) complete.",
|
||||||
|
- iface);
|
||||||
|
+ nm_log (LOGD_DEVICE, level, "Activation (%s) Stage 5 of 5 (IPv6 Commit) complete.", iface);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
@@ -4277,13 +4274,16 @@ nm_device_activate_ip6_config_commit (gpointer user_data)
|
||||||
|
void
|
||||||
|
nm_device_activate_schedule_ip6_config_result (NMDevice *self)
|
||||||
|
{
|
||||||
|
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
|
+ guint level = (priv->ip6_state == IP_DONE) ? LOGL_DEBUG : LOGL_INFO;
|
||||||
|
+
|
||||||
|
g_return_if_fail (NM_IS_DEVICE (self));
|
||||||
|
|
||||||
|
activation_source_schedule (self, nm_device_activate_ip6_config_commit, AF_INET6);
|
||||||
|
|
||||||
|
- nm_log_info (LOGD_DEVICE | LOGD_IP6,
|
||||||
|
- "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...",
|
||||||
|
- nm_device_get_iface (self));
|
||||||
|
+ nm_log (LOGD_DEVICE | LOGD_IP6, level,
|
||||||
|
+ "Activation (%s) Stage 5 of 5 (IPv6 Commit) scheduled...",
|
||||||
|
+ nm_device_get_iface (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
From 3391fa810ca323203b036a68af7f3c5802280918 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
|
||||||
|
Date: Wed, 22 Jan 2014 10:03:44 +0100
|
||||||
|
Subject: [PATCH] libnm-glib: export missing get_gateway() and get_searches()
|
||||||
|
functions
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
They were added by db9b7e10aca5456ec4960b75617e032209b98bc1 commit.
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
libnm-glib/libnm-glib.ver | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
|
||||||
|
index cb7b599..bf69db4 100644
|
||||||
|
--- a/libnm-glib/libnm-glib.ver
|
||||||
|
+++ b/libnm-glib/libnm-glib.ver
|
||||||
|
@@ -215,8 +215,10 @@ global:
|
||||||
|
nm_dhcp6_config_new;
|
||||||
|
nm_ip4_config_get_addresses;
|
||||||
|
nm_ip4_config_get_domains;
|
||||||
|
+ nm_ip4_config_get_gateway;
|
||||||
|
nm_ip4_config_get_nameservers;
|
||||||
|
nm_ip4_config_get_routes;
|
||||||
|
+ nm_ip4_config_get_searches;
|
||||||
|
nm_ip4_config_get_type;
|
||||||
|
nm_ip4_config_get_wins_servers;
|
||||||
|
nm_ip4_config_new;
|
||||||
|
@@ -224,8 +226,10 @@ global:
|
||||||
|
nm_ip6_address_object_array_get_type;
|
||||||
|
nm_ip6_config_get_addresses;
|
||||||
|
nm_ip6_config_get_domains;
|
||||||
|
+ nm_ip6_config_get_gateway;
|
||||||
|
nm_ip6_config_get_nameservers;
|
||||||
|
nm_ip6_config_get_routes;
|
||||||
|
+ nm_ip6_config_get_searches;
|
||||||
|
nm_ip6_config_get_type;
|
||||||
|
nm_ip6_config_new;
|
||||||
|
nm_ip6_route_object_array_get_type;
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
From 041f449a910a48716bc88fa56287c4213a2dcb11 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dan Winship <danw@gnome.org>
|
||||||
|
Date: Wed, 22 Jan 2014 13:20:18 -0500
|
||||||
|
Subject: [PATCH] platform: fix linux nm_platform_link_get_physical_port_id()
|
||||||
|
(rh #804527)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
It was reading the wrong property name
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/platform/nm-linux-platform.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
|
||||||
|
index 83cbc49..8e85c59 100644
|
||||||
|
--- a/src/platform/nm-linux-platform.c
|
||||||
|
+++ b/src/platform/nm-linux-platform.c
|
||||||
|
@@ -1765,7 +1765,7 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
||||||
|
if (!ifname)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- path = g_strdup_printf ("/sys/class/net/%s/physical_port_id", ifname);
|
||||||
|
+ path = g_strdup_printf ("/sys/class/net/%s/phys_port_id", ifname);
|
||||||
|
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
id = sysctl_get (platform, path);
|
||||||
|
else
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
From 85272df6eb89682a3d13022281085b97527955e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
|
||||||
|
Date: Wed, 22 Jan 2014 15:40:22 +0100
|
||||||
|
Subject: [PATCH] examples: update get_ips.py python example for DNS
|
||||||
|
information
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
examples/python/gi/get_ips.py | 44 +++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 40 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/examples/python/gi/get_ips.py b/examples/python/gi/get_ips.py
|
||||||
|
index b1e59e2..6903b6d 100755
|
||||||
|
--- a/examples/python/gi/get_ips.py
|
||||||
|
+++ b/examples/python/gi/get_ips.py
|
||||||
|
@@ -24,8 +24,8 @@ import sys, socket, struct
|
||||||
|
from gi.repository import GLib, NetworkManager, NMClient
|
||||||
|
|
||||||
|
#
|
||||||
|
-# This example shows how to get get addresses and routes from NMIP4Config and NMIP6Config
|
||||||
|
-# (got out of NMDevice)
|
||||||
|
+# This example shows how to get addresses, routes and DNS information
|
||||||
|
+# from NMIP4Config and NMIP6Config (got out of NMDevice)
|
||||||
|
#
|
||||||
|
|
||||||
|
def show_addresses(self, family):
|
||||||
|
@@ -59,7 +59,6 @@ def show_addresses(self, family):
|
||||||
|
socket.inet_ntop(family, gateway_struct))
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
def show_routes(self, family):
|
||||||
|
if (family == socket.AF_INET):
|
||||||
|
ip_cfg = self.get_ip4_config()
|
||||||
|
@@ -70,7 +69,7 @@ def show_routes(self, family):
|
||||||
|
print("None")
|
||||||
|
return
|
||||||
|
|
||||||
|
- nm_routes = ip_cfg.get_routes()
|
||||||
|
+ nm_routes = ip_cfg.get_routes()
|
||||||
|
if len(nm_routes) == 0:
|
||||||
|
print("None")
|
||||||
|
return
|
||||||
|
@@ -93,6 +92,33 @@ def show_routes(self, family):
|
||||||
|
metric)
|
||||||
|
|
||||||
|
|
||||||
|
+def show_dns(self, family):
|
||||||
|
+ if (family == socket.AF_INET):
|
||||||
|
+ ip_cfg = self.get_ip4_config()
|
||||||
|
+ else:
|
||||||
|
+ ip_cfg = self.get_ip6_config()
|
||||||
|
+
|
||||||
|
+ if ip_cfg is None:
|
||||||
|
+ print("None")
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ if (family == socket.AF_INET):
|
||||||
|
+ print ("Domains: %s") % (ip_cfg.get_domains())
|
||||||
|
+ print ("Searches: %s") % (ip_cfg.get_searches())
|
||||||
|
+ print("Nameservers:")
|
||||||
|
+ nameservers = ip_cfg.get_nameservers()
|
||||||
|
+ for dns in nameservers:
|
||||||
|
+ print socket.inet_ntop(family, struct.pack("=I", dns))
|
||||||
|
+ else:
|
||||||
|
+ print ("Domains: %s") % (ip_cfg.get_domains())
|
||||||
|
+ print ("Searches: %s") % (ip_cfg.get_searches())
|
||||||
|
+ print("Nameservers:")
|
||||||
|
+ num = ip_cfg.get_num_nameservers()
|
||||||
|
+ for i in range(0,num):
|
||||||
|
+ dns = ip_cfg.get_nameserver(i)
|
||||||
|
+ print socket.inet_ntop(family, dns)
|
||||||
|
+
|
||||||
|
+
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
sys.exit('Usage: %s <interface>' % sys.argv[0])
|
||||||
|
@@ -125,3 +151,13 @@ if __name__ == "__main__":
|
||||||
|
show_routes(dev, socket.AF_INET6)
|
||||||
|
print
|
||||||
|
|
||||||
|
+ print "IPv4 DNS:"
|
||||||
|
+ print("------------")
|
||||||
|
+ show_dns(dev, socket.AF_INET)
|
||||||
|
+ print
|
||||||
|
+
|
||||||
|
+ print "IPv6 DNS:"
|
||||||
|
+ print("------------")
|
||||||
|
+ show_dns(dev, socket.AF_INET6)
|
||||||
|
+ print
|
||||||
|
+
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
From 8ee4f58e9ee67df2ef761a691dec55c6008ad4ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
|
||||||
|
Date: Wed, 22 Jan 2014 15:31:56 +0100
|
||||||
|
Subject: [PATCH] libnm-glib: additional functions to get nameservers (rh
|
||||||
|
#1056146)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This commit adds two new functions for introspection users to get nameservers:
|
||||||
|
guint32 nm_ip6_config_get_num_nameservers (NMIP6Config *config)
|
||||||
|
const struct in6_addr *nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx)
|
||||||
|
The existing function can't be used due to GObject introspection limitations:
|
||||||
|
const GSList *nm_ip6_config_get_nameservers (NMIP6Config *config);
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1056146
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
libnm-glib/libnm-glib.ver | 2 ++
|
||||||
|
libnm-glib/nm-ip6-config.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
libnm-glib/nm-ip6-config.h | 16 +++++++-------
|
||||||
|
3 files changed, 62 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
|
||||||
|
index bf69db4..9f0db93 100644
|
||||||
|
--- a/libnm-glib/libnm-glib.ver
|
||||||
|
+++ b/libnm-glib/libnm-glib.ver
|
||||||
|
@@ -227,7 +227,9 @@ global:
|
||||||
|
nm_ip6_config_get_addresses;
|
||||||
|
nm_ip6_config_get_domains;
|
||||||
|
nm_ip6_config_get_gateway;
|
||||||
|
+ nm_ip6_config_get_nameserver;
|
||||||
|
nm_ip6_config_get_nameservers;
|
||||||
|
+ nm_ip6_config_get_num_nameservers;
|
||||||
|
nm_ip6_config_get_routes;
|
||||||
|
nm_ip6_config_get_searches;
|
||||||
|
nm_ip6_config_get_type;
|
||||||
|
diff --git a/libnm-glib/nm-ip6-config.c b/libnm-glib/nm-ip6-config.c
|
||||||
|
index 01e2cae..7c9cfca 100644
|
||||||
|
--- a/libnm-glib/nm-ip6-config.c
|
||||||
|
+++ b/libnm-glib/nm-ip6-config.c
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||||
|
- * Copyright (C) 2008 - 2011 Red Hat, Inc.
|
||||||
|
+ * Copyright (C) 2008 - 2014 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
@@ -192,6 +192,56 @@ nm_ip6_config_get_addresses (NMIP6Config *config)
|
||||||
|
return NM_IP6_CONFIG_GET_PRIVATE (config)->addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * nm_ip6_config_get_num_nameservers:
|
||||||
|
+ * @config: a #NMIP6Config
|
||||||
|
+ *
|
||||||
|
+ * Gets the number of the domain name servers in the configuration.
|
||||||
|
+ *
|
||||||
|
+ * Returns: the number of domain name servers
|
||||||
|
+ *
|
||||||
|
+ * Since: 0.9.10
|
||||||
|
+ **/
|
||||||
|
+guint32
|
||||||
|
+nm_ip6_config_get_num_nameservers (NMIP6Config *config)
|
||||||
|
+{
|
||||||
|
+ g_return_val_if_fail (NM_IS_IP6_CONFIG (config), 0);
|
||||||
|
+
|
||||||
|
+ _nm_object_ensure_inited (NM_OBJECT (config));
|
||||||
|
+ return g_slist_length (NM_IP6_CONFIG_GET_PRIVATE (config)->nameservers);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * nm_ip6_config_get_nameserver:
|
||||||
|
+ * @config: a #NMIP6Config
|
||||||
|
+ * @idx: index of the nameserver to return
|
||||||
|
+ *
|
||||||
|
+ * Gets the domain name server at index @idx in the configuration.
|
||||||
|
+ *
|
||||||
|
+ * Returns: (array fixed-size=16) (element-type guint8) (transfer none):
|
||||||
|
+ * the IPv6 address of domain name server at index @iidx
|
||||||
|
+ *
|
||||||
|
+ * Since: 0.9.10
|
||||||
|
+ **/
|
||||||
|
+const struct in6_addr *
|
||||||
|
+nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx)
|
||||||
|
+{
|
||||||
|
+ NMIP6ConfigPrivate *priv;
|
||||||
|
+ GSList *item;
|
||||||
|
+ guint32 i = 0;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
|
||||||
|
+
|
||||||
|
+ _nm_object_ensure_inited (NM_OBJECT (config));
|
||||||
|
+ priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||||
|
+
|
||||||
|
+ for (item = priv->nameservers; item && i < idx; i++)
|
||||||
|
+ item = item->next;
|
||||||
|
+
|
||||||
|
+ g_return_val_if_fail (item, NULL);
|
||||||
|
+ return item ? (const struct in6_addr *) item->data : NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* FIXME: like in libnm_util, in6_addr is not introspectable, so skipping here */
|
||||||
|
/**
|
||||||
|
* nm_ip6_config_get_nameservers: (skip)
|
||||||
|
diff --git a/libnm-glib/nm-ip6-config.h b/libnm-glib/nm-ip6-config.h
|
||||||
|
index a71d74b..b6198fa 100644
|
||||||
|
--- a/libnm-glib/nm-ip6-config.h
|
||||||
|
+++ b/libnm-glib/nm-ip6-config.h
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
* Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||||
|
- * Copyright (C) 2008 Red Hat, Inc.
|
||||||
|
+ * Copyright (C) 2008 - 2014 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NM_IP6_CONFIG_H
|
||||||
|
@@ -65,12 +65,14 @@ GType nm_ip6_config_get_type (void);
|
||||||
|
|
||||||
|
GObject *nm_ip6_config_new (DBusGConnection *connection, const char *object_path);
|
||||||
|
|
||||||
|
-const char * nm_ip6_config_get_gateway (NMIP6Config *config);
|
||||||
|
-const GSList * nm_ip6_config_get_addresses (NMIP6Config *config);
|
||||||
|
-const GSList * nm_ip6_config_get_routes (NMIP6Config *config);
|
||||||
|
-const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config);
|
||||||
|
-const GPtrArray *nm_ip6_config_get_domains (NMIP6Config *config);
|
||||||
|
-const GPtrArray *nm_ip6_config_get_searches (NMIP6Config *config);
|
||||||
|
+const char * nm_ip6_config_get_gateway (NMIP6Config *config);
|
||||||
|
+const GSList * nm_ip6_config_get_addresses (NMIP6Config *config);
|
||||||
|
+const GSList * nm_ip6_config_get_routes (NMIP6Config *config);
|
||||||
|
+guint32 nm_ip6_config_get_num_nameservers (NMIP6Config *config);
|
||||||
|
+const struct in6_addr *nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx);
|
||||||
|
+const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config);
|
||||||
|
+const GPtrArray * nm_ip6_config_get_domains (NMIP6Config *config);
|
||||||
|
+const GPtrArray * nm_ip6_config_get_searches (NMIP6Config *config);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
From df4c9347fc85ec2aa7ddc67e0ff39bc1d56f669a Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <jklimes@redhat.com>
|
||||||
|
Date: Mon, 27 Jan 2014 17:36:30 +0100
|
||||||
|
Subject: [PATCH] libnm-glib: chain up the parent constructed() of
|
||||||
|
NMRemoteConnection
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
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 73a2cc8..27baebd 100644
|
||||||
|
--- a/libnm-glib/nm-remote-connection.c
|
||||||
|
+++ b/libnm-glib/nm-remote-connection.c
|
||||||
|
@@ -508,6 +508,8 @@ constructed (GObject *object)
|
||||||
|
{
|
||||||
|
NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
|
||||||
|
|
||||||
|
+ G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructed (object);
|
||||||
|
+
|
||||||
|
g_assert (priv->bus);
|
||||||
|
g_assert (nm_connection_get_path (NM_CONNECTION (object)));
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,293 @@
|
||||||
|
From d7c369712b9e6298d62303899e372ab7d27a92d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dan Williams <dcbw@redhat.com>
|
||||||
|
Date: Mon, 23 Dec 2013 12:21:09 -0600
|
||||||
|
Subject: [PATCH] vpn: handle missing tunnel interface for IP-based VPNs (bgo
|
||||||
|
#721724) (rh #1030068)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
IPSec-based VPNs that use the kernel IPSec stack don't have tunnel
|
||||||
|
interfaces, and the IP details (address, routes) get added directly
|
||||||
|
to the parent network device. NetworkManager previously required
|
||||||
|
a tunnel interface and failed the VPN if one was not provided.
|
||||||
|
|
||||||
|
When no tunnel interface is passed, construct the VPN IP configuration
|
||||||
|
using available details and pass that to the NMDevice as the VPN IP
|
||||||
|
config. The device will merge that config with its own and apply
|
||||||
|
any configuration that the kernel/VPN has not already applied.
|
||||||
|
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=721724
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1030068
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=865883
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=845599
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/nm-policy.c | 15 +++--
|
||||||
|
src/vpn-manager/nm-vpn-connection.c | 112 ++++++++++++++++++++++--------------
|
||||||
|
2 files changed, 79 insertions(+), 48 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nm-policy.c b/src/nm-policy.c
|
||||||
|
index 92ec1ab..090cd04 100644
|
||||||
|
--- a/src/nm-policy.c
|
||||||
|
+++ b/src/nm-policy.c
|
||||||
|
@@ -655,17 +655,21 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update)
|
||||||
|
in_addr_t int_gw = nm_vpn_connection_get_ip4_internal_gateway (vpn);
|
||||||
|
int mss = nm_ip4_config_get_mss (ip4_config);
|
||||||
|
|
||||||
|
+ /* If no VPN interface, use the parent interface */
|
||||||
|
+ if (ip_ifindex <= 0)
|
||||||
|
+ ip_ifindex = parent_ifindex;
|
||||||
|
+
|
||||||
|
if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, 0, mss)) {
|
||||||
|
nm_platform_ip4_route_add (parent_ifindex, gw_addr, 32, 0, 0, parent_mss);
|
||||||
|
- if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, 0, mss)) {
|
||||||
|
+ if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, int_gw, 0, mss))
|
||||||
|
nm_log_err (LOGD_IP4 | LOGD_VPN, "Failed to set default route.");
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
default_device = nm_vpn_connection_get_parent_device (vpn);
|
||||||
|
} else {
|
||||||
|
int mss = nm_ip4_config_get_mss (ip4_config);
|
||||||
|
|
||||||
|
+ g_assert (ip_iface);
|
||||||
|
if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, 0, mss)) {
|
||||||
|
nm_platform_ip4_route_add (ip_ifindex, gw_addr, 32, 0, 0, mss);
|
||||||
|
if (!nm_platform_ip4_route_add (ip_ifindex, 0, 0, gw_addr, 0, mss)) {
|
||||||
|
@@ -845,6 +849,10 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update)
|
||||||
|
if (!int_gw)
|
||||||
|
int_gw = &in6addr_any;
|
||||||
|
|
||||||
|
+ /* If no VPN interface, use the parent interface */
|
||||||
|
+ if (ip_ifindex <= 0)
|
||||||
|
+ ip_ifindex = parent_ifindex;
|
||||||
|
+
|
||||||
|
if (!nm_platform_ip6_route_add (ip_ifindex, 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)) {
|
||||||
|
@@ -858,9 +866,8 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update)
|
||||||
|
|
||||||
|
if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)) {
|
||||||
|
nm_platform_ip6_route_add (ip_ifindex, *gw_addr, 128, in6addr_any, 0, mss);
|
||||||
|
- if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss)) {
|
||||||
|
+ if (!nm_platform_ip6_route_add (ip_ifindex, in6addr_any, 0, *gw_addr, 0, mss))
|
||||||
|
nm_log_err (LOGD_IP6, "Failed to set default route.");
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
default_device6 = best;
|
||||||
|
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
|
||||||
|
index 8541f10..f1d7d46 100644
|
||||||
|
--- a/src/vpn-manager/nm-vpn-connection.c
|
||||||
|
+++ b/src/vpn-manager/nm-vpn-connection.c
|
||||||
|
@@ -301,13 +301,13 @@ device_state_changed (NMActiveConnection *active,
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
||||||
|
+add_ip4_vpn_gateway_route (NMIP4Config *config, NMDevice *parent_device, guint32 vpn_gw)
|
||||||
|
{
|
||||||
|
NMIP4Config *parent_config;
|
||||||
|
guint32 parent_gw;
|
||||||
|
NMPlatformIP4Route route;
|
||||||
|
- NMIP4Config *vpn4_config;
|
||||||
|
|
||||||
|
+ g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
||||||
|
g_return_if_fail (NM_IS_DEVICE (parent_device));
|
||||||
|
g_return_if_fail (vpn_gw != 0);
|
||||||
|
|
||||||
|
@@ -321,8 +321,6 @@ add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
||||||
|
if (!parent_gw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- vpn4_config = nm_ip4_config_new ();
|
||||||
|
-
|
||||||
|
memset (&route, 0, sizeof (route));
|
||||||
|
route.network = vpn_gw;
|
||||||
|
route.plen = 32;
|
||||||
|
@@ -335,7 +333,7 @@ add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
||||||
|
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
|
||||||
|
route.gateway = 0;
|
||||||
|
|
||||||
|
- nm_ip4_config_add_route (vpn4_config, &route);
|
||||||
|
+ nm_ip4_config_add_route (config, &route);
|
||||||
|
|
||||||
|
/* Ensure there's a route to the parent device's gateway through the
|
||||||
|
* parent device, since if the VPN claims the default route and the VPN
|
||||||
|
@@ -346,21 +344,19 @@ add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
|
||||||
|
route.network = parent_gw;
|
||||||
|
route.plen = 32;
|
||||||
|
|
||||||
|
- nm_ip4_config_add_route (vpn4_config, &route);
|
||||||
|
-
|
||||||
|
- nm_device_set_vpn4_config (parent_device, vpn4_config);
|
||||||
|
- g_object_unref (vpn4_config);
|
||||||
|
+ nm_ip4_config_add_route (config, &route);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||||
|
+add_ip6_vpn_gateway_route (NMIP6Config *config,
|
||||||
|
+ NMDevice *parent_device,
|
||||||
|
const struct in6_addr *vpn_gw)
|
||||||
|
{
|
||||||
|
NMIP6Config *parent_config;
|
||||||
|
const struct in6_addr *parent_gw;
|
||||||
|
NMPlatformIP6Route route;
|
||||||
|
- NMIP6Config *vpn6_config;
|
||||||
|
|
||||||
|
+ g_return_if_fail (NM_IS_IP6_CONFIG (config));
|
||||||
|
g_return_if_fail (NM_IS_DEVICE (parent_device));
|
||||||
|
g_return_if_fail (vpn_gw != NULL);
|
||||||
|
|
||||||
|
@@ -370,8 +366,6 @@ add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||||
|
if (!parent_gw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- vpn6_config = nm_ip6_config_new ();
|
||||||
|
-
|
||||||
|
memset (&route, 0, sizeof (route));
|
||||||
|
route.network = *vpn_gw;
|
||||||
|
route.plen = 128;
|
||||||
|
@@ -384,7 +378,7 @@ add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||||
|
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
|
||||||
|
route.gateway = in6addr_any;
|
||||||
|
|
||||||
|
- nm_ip6_config_add_route (vpn6_config, &route);
|
||||||
|
+ nm_ip6_config_add_route (config, &route);
|
||||||
|
|
||||||
|
/* Ensure there's a route to the parent device's gateway through the
|
||||||
|
* parent device, since if the VPN claims the default route and the VPN
|
||||||
|
@@ -395,10 +389,7 @@ add_ip6_vpn_gateway_route (NMDevice *parent_device,
|
||||||
|
route.network = *parent_gw;
|
||||||
|
route.plen = 128;
|
||||||
|
|
||||||
|
- nm_ip6_config_add_route (vpn6_config, &route);
|
||||||
|
-
|
||||||
|
- nm_device_set_vpn6_config (parent_device, vpn6_config);
|
||||||
|
- g_object_unref (vpn6_config);
|
||||||
|
+ nm_ip6_config_add_route (config, &route);
|
||||||
|
}
|
||||||
|
|
||||||
|
NMVPNConnection *
|
||||||
|
@@ -601,7 +592,7 @@ print_vpn_config (NMVPNConnection *connection)
|
||||||
|
ip6_address_to_string (priv->ip6_external_gw));
|
||||||
|
}
|
||||||
|
|
||||||
|
- nm_log_info (LOGD_VPN, "Tunnel Device: %s", priv->ip_iface);
|
||||||
|
+ nm_log_info (LOGD_VPN, "Tunnel Device: %s", priv->ip_iface ? priv->ip_iface : "(none)");
|
||||||
|
|
||||||
|
if (priv->ip4_config) {
|
||||||
|
nm_log_info (LOGD_VPN, "IPv4 configuration:");
|
||||||
|
@@ -692,25 +683,54 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
|
||||||
|
nm_vpn_connection_apply_config (NMVPNConnection *connection)
|
||||||
|
{
|
||||||
|
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||||
|
+ NMIP4Config *vpn4_parent_config = NULL;
|
||||||
|
+ NMIP6Config *vpn6_parent_config = NULL;
|
||||||
|
|
||||||
|
- nm_platform_link_set_up (priv->ip_ifindex);
|
||||||
|
+ if (priv->ip_ifindex > 0) {
|
||||||
|
+ nm_platform_link_set_up (priv->ip_ifindex);
|
||||||
|
|
||||||
|
- if (priv->ip4_config) {
|
||||||
|
- if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex, 0))
|
||||||
|
- return FALSE;
|
||||||
|
+ if (priv->ip4_config) {
|
||||||
|
+ if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex, 0))
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (priv->ip6_config) {
|
||||||
|
+ if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex, 0))
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (priv->ip4_config)
|
||||||
|
+ vpn4_parent_config = nm_ip4_config_new ();
|
||||||
|
+ if (priv->ip6_config)
|
||||||
|
+ vpn6_parent_config = nm_ip6_config_new ();
|
||||||
|
+ } else {
|
||||||
|
+ /* If the VPN didn't return a network interface, it is a route-based
|
||||||
|
+ * VPN (like kernel IPSec) and all IP addressing and routing should
|
||||||
|
+ * be done on the parent interface instead.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ if (priv->ip4_config)
|
||||||
|
+ vpn4_parent_config = g_object_ref (priv->ip4_config);
|
||||||
|
+ if (priv->ip6_config)
|
||||||
|
+ vpn6_parent_config = g_object_ref (priv->ip6_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (priv->ip6_config) {
|
||||||
|
- if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex, 0))
|
||||||
|
- /* FIXME: remove ip4 config */
|
||||||
|
- return FALSE;
|
||||||
|
+ if (vpn4_parent_config) {
|
||||||
|
+ /* Add any explicit route to the VPN gateway through the parent device */
|
||||||
|
+ if (priv->ip4_external_gw)
|
||||||
|
+ add_ip4_vpn_gateway_route (vpn4_parent_config, priv->parent_dev, priv->ip4_external_gw);
|
||||||
|
+
|
||||||
|
+ nm_device_set_vpn4_config (priv->parent_dev, vpn4_parent_config);
|
||||||
|
+ g_object_unref (vpn4_parent_config);
|
||||||
|
}
|
||||||
|
+ if (vpn6_parent_config) {
|
||||||
|
+ /* Add any explicit route to the VPN gateway through the parent device */
|
||||||
|
+ if (priv->ip6_external_gw)
|
||||||
|
+ add_ip6_vpn_gateway_route (vpn6_parent_config, priv->parent_dev, priv->ip6_external_gw);
|
||||||
|
|
||||||
|
- /* Add any explicit route to the VPN gateway through the parent device */
|
||||||
|
- if (priv->ip4_external_gw)
|
||||||
|
- add_ip4_vpn_gateway_route (priv->parent_dev, priv->ip4_external_gw);
|
||||||
|
- if (priv->ip6_external_gw)
|
||||||
|
- add_ip6_vpn_gateway_route (priv->parent_dev, priv->ip6_external_gw);
|
||||||
|
+ nm_device_set_vpn6_config (priv->parent_dev, vpn6_parent_config);
|
||||||
|
+ g_object_unref (vpn6_parent_config);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
nm_log_info (LOGD_VPN, "VPN connection '%s' (IP Config Get) complete.",
|
||||||
|
nm_connection_get_id (priv->connection));
|
||||||
|
@@ -768,21 +788,25 @@ process_generic_config (NMVPNConnection *connection,
|
||||||
|
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||||
|
GValue *val;
|
||||||
|
|
||||||
|
+ g_clear_pointer (&priv->ip_iface, g_free);
|
||||||
|
+
|
||||||
|
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CONFIG_TUNDEV);
|
||||||
|
- if (val)
|
||||||
|
- priv->ip_iface = g_strdup (g_value_get_string (val));
|
||||||
|
- else {
|
||||||
|
- nm_log_err (LOGD_VPN, "invalid or missing tunnel device received!");
|
||||||
|
- nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
||||||
|
- return FALSE;
|
||||||
|
+ if (val) {
|
||||||
|
+ const char *tmp = g_value_get_string (val);
|
||||||
|
+
|
||||||
|
+ /* Backwards compat with NM-openswan */
|
||||||
|
+ if (g_strcmp0 (tmp, "_none_") != 0)
|
||||||
|
+ priv->ip_iface = g_strdup (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Grab the interface index for address/routing operations */
|
||||||
|
- priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface);
|
||||||
|
- if (!priv->ip_ifindex) {
|
||||||
|
- nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface);
|
||||||
|
- nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
||||||
|
- return FALSE;
|
||||||
|
+ if (priv->ip_iface) {
|
||||||
|
+ /* Grab the interface index for address/routing operations */
|
||||||
|
+ priv->ip_ifindex = nm_platform_link_get_ifindex (priv->ip_iface);
|
||||||
|
+ if (!priv->ip_ifindex) {
|
||||||
|
+ nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface);
|
||||||
|
+ nm_vpn_connection_config_maybe_complete (connection, FALSE);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_CONFIG_BANNER);
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
From a9f1d121783a7f3c65c9f47d3419b5a8a255fe47 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dan Williams <dcbw@redhat.com>
|
||||||
|
Date: Thu, 23 Jan 2014 12:16:02 -0600
|
||||||
|
Subject: [PATCH] dhcp: don't add an IPv6 address if one wasn't given (rh
|
||||||
|
#1048046)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
In information-only mode (where RA is providing addresses), DHCPv6
|
||||||
|
may not give an address. NetworkManager was adding a blank one
|
||||||
|
anyway, which is invalid. Don't do that.
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/dhcp-manager/nm-dhcp-client.c | 16 +++++++---------
|
||||||
|
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
index 75cd818..57298c8 100644
|
||||||
|
--- a/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
+++ b/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
@@ -1404,6 +1404,12 @@ ip6_options_to_config (NMDHCPClient *self)
|
||||||
|
|
||||||
|
ip6_config = nm_ip6_config_new ();
|
||||||
|
|
||||||
|
+ str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time");
|
||||||
|
+ if (str) {
|
||||||
|
+ address.lifetime = address.preferred = strtoul (str, NULL, 10);
|
||||||
|
+ nm_log_info (LOGD_DHCP6, " lease time %d", address.lifetime);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
str = g_hash_table_lookup (priv->options, "new_ip6_address");
|
||||||
|
if (str) {
|
||||||
|
if (!inet_pton (AF_INET6, str, &tmp_addr)) {
|
||||||
|
@@ -1413,21 +1419,13 @@ ip6_options_to_config (NMDHCPClient *self)
|
||||||
|
}
|
||||||
|
|
||||||
|
address.address = tmp_addr;
|
||||||
|
+ nm_ip6_config_add_address (ip6_config, &address);
|
||||||
|
nm_log_info (LOGD_DHCP6, " address %s", str);
|
||||||
|
-
|
||||||
|
} else if (priv->info_only == FALSE) {
|
||||||
|
/* No address in Managed mode is a hard error */
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
- str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time");
|
||||||
|
- if (str) {
|
||||||
|
- address.lifetime = address.preferred = strtoul (str, NULL, 10);
|
||||||
|
- nm_log_info (LOGD_DHCP6, " lease time %d", address.lifetime);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- nm_ip6_config_add_address (ip6_config, &address);
|
||||||
|
-
|
||||||
|
str = g_hash_table_lookup (priv->options, "new_host_name");
|
||||||
|
if (str)
|
||||||
|
nm_log_info (LOGD_DHCP6, " hostname '%s'", str);
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
From e62b212be3b51b0dc31fd12ea70d78358164063e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dan Williams <dcbw@redhat.com>
|
||||||
|
Date: Fri, 24 Jan 2014 12:49:57 -0600
|
||||||
|
Subject: [PATCH] core: exit cleanly if D-Bus cannot be initialized (rh
|
||||||
|
#1057738)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Instead of crashing, let's exit cleanly.
|
||||||
|
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/nm-manager.c | 90 ++++++++++++++++++++++++++++++--------------------------
|
||||||
|
1 file changed, 49 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/nm-manager.c b/src/nm-manager.c
|
||||||
|
index e6ff8d5..1545e72 100644
|
||||||
|
--- a/src/nm-manager.c
|
||||||
|
+++ b/src/nm-manager.c
|
||||||
|
@@ -217,6 +217,7 @@ typedef struct {
|
||||||
|
|
||||||
|
NMDBusManager *dbus_mgr;
|
||||||
|
guint dbus_connection_changed_id;
|
||||||
|
+ gboolean prop_filter_added;
|
||||||
|
NMAtmManager *atm_mgr;
|
||||||
|
NMRfkillManager *rfkill_mgr;
|
||||||
|
NMBluezManager *bluez_mgr;
|
||||||
|
@@ -250,7 +251,6 @@ typedef struct {
|
||||||
|
GHashTable *nm_bridges;
|
||||||
|
|
||||||
|
gboolean startup;
|
||||||
|
- gboolean disposed;
|
||||||
|
} NMManagerPrivate;
|
||||||
|
|
||||||
|
#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
|
||||||
|
@@ -4503,6 +4503,16 @@ nm_manager_new (NMSettings *settings,
|
||||||
|
|
||||||
|
priv = NM_MANAGER_GET_PRIVATE (singleton);
|
||||||
|
|
||||||
|
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||||
|
+ if (!bus) {
|
||||||
|
+ nm_log_err (LOGD_CORE, "Failed to initialize D-Bus connection");
|
||||||
|
+ g_object_unref (singleton);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dbus_connection = dbus_g_connection_get_connection (bus);
|
||||||
|
+ g_assert (dbus_connection);
|
||||||
|
+
|
||||||
|
priv->policy = nm_policy_new (singleton, settings);
|
||||||
|
g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE,
|
||||||
|
G_CALLBACK (policy_default_device_changed), singleton);
|
||||||
|
@@ -4517,16 +4527,12 @@ nm_manager_new (NMSettings *settings,
|
||||||
|
g_signal_connect (priv->connectivity, "notify::" NM_CONNECTIVITY_STATE,
|
||||||
|
G_CALLBACK (connectivity_changed), singleton);
|
||||||
|
|
||||||
|
- bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||||
|
- g_assert (bus);
|
||||||
|
- dbus_connection = dbus_g_connection_get_connection (bus);
|
||||||
|
- g_assert (dbus_connection);
|
||||||
|
-
|
||||||
|
if (!dbus_connection_add_filter (dbus_connection, prop_filter, singleton, NULL)) {
|
||||||
|
nm_log_err (LOGD_CORE, "failed to register DBus connection filter");
|
||||||
|
g_object_unref (singleton);
|
||||||
|
return NULL;
|
||||||
|
- }
|
||||||
|
+ }
|
||||||
|
+ priv->prop_filter_added = TRUE;
|
||||||
|
|
||||||
|
priv->settings = g_object_ref (settings);
|
||||||
|
|
||||||
|
@@ -4614,14 +4620,9 @@ dispose (GObject *object)
|
||||||
|
DBusConnection *dbus_connection;
|
||||||
|
GSList *iter;
|
||||||
|
|
||||||
|
- if (priv->disposed) {
|
||||||
|
- G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
- priv->disposed = TRUE;
|
||||||
|
-
|
||||||
|
g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL);
|
||||||
|
g_slist_free (priv->auth_chains);
|
||||||
|
+ priv->auth_chains = NULL;
|
||||||
|
|
||||||
|
nm_auth_changed_func_unregister (authority_changed_cb, manager);
|
||||||
|
|
||||||
|
@@ -4635,8 +4636,7 @@ dispose (GObject *object)
|
||||||
|
|
||||||
|
for (iter = priv->active_connections; iter; iter = g_slist_next (iter))
|
||||||
|
active_connection_removed (manager, NM_ACTIVE_CONNECTION (iter->data));
|
||||||
|
- g_slist_free (priv->active_connections);
|
||||||
|
- priv->active_connections = NULL;
|
||||||
|
+ g_clear_pointer (&priv->active_connections, g_slist_free);
|
||||||
|
g_clear_object (&priv->primary_connection);
|
||||||
|
g_clear_object (&priv->activating_connection);
|
||||||
|
|
||||||
|
@@ -4644,12 +4644,14 @@ dispose (GObject *object)
|
||||||
|
|
||||||
|
g_free (priv->hostname);
|
||||||
|
|
||||||
|
- g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_default_device_changed), singleton);
|
||||||
|
- g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_activating_device_changed), singleton);
|
||||||
|
- g_object_unref (priv->policy);
|
||||||
|
+ if (priv->policy) {
|
||||||
|
+ g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_default_device_changed), singleton);
|
||||||
|
+ g_signal_handlers_disconnect_by_func (priv->policy, G_CALLBACK (policy_activating_device_changed), singleton);
|
||||||
|
+ g_clear_object (&priv->policy);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- g_object_unref (priv->settings);
|
||||||
|
- g_object_unref (priv->vpn_manager);
|
||||||
|
+ g_clear_object (&priv->settings);
|
||||||
|
+ g_clear_object (&priv->vpn_manager);
|
||||||
|
|
||||||
|
if (priv->modem_added_id) {
|
||||||
|
g_source_remove (priv->modem_added_id);
|
||||||
|
@@ -4659,39 +4661,42 @@ dispose (GObject *object)
|
||||||
|
g_source_remove (priv->modem_removed_id);
|
||||||
|
priv->modem_removed_id = 0;
|
||||||
|
}
|
||||||
|
- g_object_unref (priv->modem_manager);
|
||||||
|
+ g_clear_object (&priv->modem_manager);
|
||||||
|
|
||||||
|
/* Unregister property filter */
|
||||||
|
- bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||||
|
- if (bus) {
|
||||||
|
- dbus_connection = dbus_g_connection_get_connection (bus);
|
||||||
|
- g_assert (dbus_connection);
|
||||||
|
- dbus_connection_remove_filter (dbus_connection, prop_filter, manager);
|
||||||
|
+ if (priv->dbus_mgr) {
|
||||||
|
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||||
|
+ if (bus) {
|
||||||
|
+ dbus_connection = dbus_g_connection_get_connection (bus);
|
||||||
|
+ if (dbus_connection && priv->prop_filter_added) {
|
||||||
|
+ dbus_connection_remove_filter (dbus_connection, prop_filter, manager);
|
||||||
|
+ priv->prop_filter_added = FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ g_signal_handler_disconnect (priv->dbus_mgr, priv->dbus_connection_changed_id);
|
||||||
|
+ priv->dbus_mgr = NULL;
|
||||||
|
}
|
||||||
|
- g_signal_handler_disconnect (priv->dbus_mgr, priv->dbus_connection_changed_id);
|
||||||
|
- priv->dbus_mgr = NULL;
|
||||||
|
-
|
||||||
|
- if (priv->bluez_mgr)
|
||||||
|
- g_object_unref (priv->bluez_mgr);
|
||||||
|
-
|
||||||
|
- if (priv->aipd_proxy)
|
||||||
|
- g_object_unref (priv->aipd_proxy);
|
||||||
|
|
||||||
|
- if (priv->sleep_monitor)
|
||||||
|
- g_object_unref (priv->sleep_monitor);
|
||||||
|
+ g_clear_object (&priv->bluez_mgr);
|
||||||
|
+ g_clear_object (&priv->aipd_proxy);
|
||||||
|
+ g_clear_object (&priv->sleep_monitor);
|
||||||
|
|
||||||
|
if (priv->fw_monitor) {
|
||||||
|
- if (priv->fw_monitor_id)
|
||||||
|
+ if (priv->fw_monitor_id) {
|
||||||
|
g_signal_handler_disconnect (priv->fw_monitor, priv->fw_monitor_id);
|
||||||
|
+ priv->fw_monitor_id = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (priv->fw_changed_id)
|
||||||
|
+ if (priv->fw_changed_id) {
|
||||||
|
g_source_remove (priv->fw_changed_id);
|
||||||
|
+ priv->fw_changed_id = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
g_file_monitor_cancel (priv->fw_monitor);
|
||||||
|
- g_object_unref (priv->fw_monitor);
|
||||||
|
+ g_clear_object (&priv->fw_monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
- g_slist_free (priv->factories);
|
||||||
|
+ g_clear_pointer (&priv->factories, g_slist_free);
|
||||||
|
|
||||||
|
if (priv->timestamp_update_id) {
|
||||||
|
g_source_remove (priv->timestamp_update_id);
|
||||||
|
@@ -4945,14 +4950,17 @@ dbus_connection_changed_cb (NMDBusManager *dbus_mgr,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NMManager *self = NM_MANAGER (user_data);
|
||||||
|
+ gboolean success = FALSE;
|
||||||
|
|
||||||
|
if (dbus_connection) {
|
||||||
|
/* Register property filter on new connection; there's no reason this
|
||||||
|
* should fail except out-of-memory or program error; if it does fail
|
||||||
|
* then there's no Manager property access control, which is bad.
|
||||||
|
*/
|
||||||
|
- g_assert (dbus_connection_add_filter (dbus_connection, prop_filter, self, NULL));
|
||||||
|
+ success = dbus_connection_add_filter (dbus_connection, prop_filter, self, NULL);
|
||||||
|
+ g_assert (success);
|
||||||
|
}
|
||||||
|
+ NM_MANAGER_GET_PRIVATE (self)->prop_filter_added = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
From 31fe84e467732463eabc8f70c2a419008e7a227c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Scott Shambarger <devel@shambarger.net>
|
||||||
|
Date: Thu, 9 Jan 2014 14:26:53 -0800
|
||||||
|
Subject: [PATCH] core: Add host route for DHCP4 server if outside assigned
|
||||||
|
subnet (bgo #721767)
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Some ISP's provide leases from central servers that are on different
|
||||||
|
subnets that the address offered. If the host does not configure the
|
||||||
|
interface as the default route, the dhcp server may not be reachable
|
||||||
|
via unicast, and a host specific route is needed.
|
||||||
|
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=721767
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=983325
|
||||||
|
|
||||||
|
Signed-off-by: Thomas Haller <thaller@redhat.com>
|
||||||
|
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
|
||||||
|
---
|
||||||
|
src/dhcp-manager/nm-dhcp-client.c | 39 +++++++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 37 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
index edea8f8..75cd818 100644
|
||||||
|
--- a/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
+++ b/src/dhcp-manager/nm-dhcp-client.c
|
||||||
|
@@ -1200,8 +1200,8 @@ ip4_options_to_config (NMDHCPClient *self)
|
||||||
|
|
||||||
|
for (s = routers; *s; s++) {
|
||||||
|
/* FIXME: how to handle multiple routers? */
|
||||||
|
- if (inet_pton (AF_INET, *s, &tmp_addr) > 0) {
|
||||||
|
- nm_ip4_config_set_gateway (ip4_config, tmp_addr);
|
||||||
|
+ if (inet_pton (AF_INET, *s, &gwaddr) > 0) {
|
||||||
|
+ nm_ip4_config_set_gateway (ip4_config, gwaddr);
|
||||||
|
nm_log_info (LOGD_DHCP4, " gateway %s", *s);
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
@@ -1211,6 +1211,41 @@ ip4_options_to_config (NMDHCPClient *self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * RFC 2132, section 9.7
|
||||||
|
+ * DHCP clients use the contents of the 'server identifier' field
|
||||||
|
+ * as the destination address for any DHCP messages unicast to
|
||||||
|
+ * the DHCP server.
|
||||||
|
+ *
|
||||||
|
+ * Some ISP's provide leases from central servers that are on
|
||||||
|
+ * different subnets that the address offered. If the host
|
||||||
|
+ * does not configure the interface as the default route, the
|
||||||
|
+ * dhcp server may not be reachable via unicast, and a host
|
||||||
|
+ * specific route is needed.
|
||||||
|
+ **/
|
||||||
|
+ str = g_hash_table_lookup (priv->options, "new_dhcp_server_identifier");
|
||||||
|
+ if (str) {
|
||||||
|
+ if (inet_pton (AF_INET, str, &tmp_addr) > 0) {
|
||||||
|
+ NMPlatformIP4Route route;
|
||||||
|
+ guint32 mask = nm_utils_ip4_prefix_to_netmask (address.plen);
|
||||||
|
+
|
||||||
|
+ nm_log_info (LOGD_DHCP4, " server identifier %s", str);
|
||||||
|
+ if ((tmp_addr & mask) != (address.address & mask)) {
|
||||||
|
+ /* DHCP server not on assigned subnet, route needed */
|
||||||
|
+ memset (&route, 0, sizeof (route));
|
||||||
|
+ route.network = tmp_addr;
|
||||||
|
+ route.plen = 32;
|
||||||
|
+ /* this will be a device route if gwaddr is 0 */
|
||||||
|
+ route.gateway = gwaddr;
|
||||||
|
+ nm_ip4_config_add_route (ip4_config, &route);
|
||||||
|
+ nm_log_dbg (LOGD_IP, "adding route for server identifier: %s",
|
||||||
|
+ nm_platform_ip4_route_to_string (&route));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time");
|
||||||
|
if (str) {
|
||||||
|
address.lifetime = address.preferred = strtoul (str, NULL, 10);
|
||||||
|
--
|
||||||
|
1.7.11.7
|
||||||
|
|
Loading…
Reference in New Issue