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:
Jiří Klimeš 2014-01-28 15:19:12 +01:00
parent d112c5a56c
commit 25f86691e2
11 changed files with 1117 additions and 1 deletions

View File

@ -19,7 +19,7 @@ Name: NetworkManager
Summary: Network connection manager and user applications
Epoch: 1
Version: 0.9.9.0
Release: 26%{snapshot}%{?dist}
Release: 27%{snapshot}%{?dist}
Group: System Environment/Base
License: GPLv2+
URL: http://www.gnome.org/projects/NetworkManager/
@ -56,6 +56,16 @@ Patch26: rh1036132-VPN-active-con-info.patch
Patch27: rh1031574-primary-connection.patch
Patch28: physical-port-id.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)
@ -208,6 +218,16 @@ deployments.
%patch27 -p1 -b .primary-connection
%patch28 -p1 -b .physical-port-id
%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
@ -406,6 +426,17 @@ fi
%config %{_sysconfdir}/%{name}/conf.d/00-server.conf
%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
- core: improve handling of NPAR/SR-IOV devices (rh #804527)
- libnm-glib: add NMDevice:physical-port-id property

View File

@ -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

View File

@ -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

View File

@ -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

98
get-ip-examples.patch Normal file
View File

@ -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

145
get-nameservers.patch Normal file
View File

@ -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

31
rem-con-constructed.patch Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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