[PATCH] firewall-manager: allow dhcpv6-client service



Tell firewall to allow dhcpv6-client service for the given zone prior
to starting dhcpv6 client. We don't need to wait for the response
because dhcp client keeps sending Solicit messages until it gets the
response (i.e. until firewall opens the port).
---
 src/Makefile.am                            |    6 ++--
 src/dhcp-manager/Makefile.am               |    2 +
 src/dhcp-manager/nm-dhcp-manager.c         |   22 ++++++++++++--
 src/dhcp-manager/nm-dhcp-manager.h         |    1 +
 src/firewall-manager/nm-firewall-manager.c |   44 ++++++++++++++++++++++++++++
 src/firewall-manager/nm-firewall-manager.h |    2 +
 src/main.c                                 |   14 ++++----
 src/nm-device.c                            |    3 ++
 8 files changed, 81 insertions(+), 13 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index f46fbab..ae84f70 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,6 +3,7 @@ SUBDIRS= \
 	logging \
 	dns-manager \
 	vpn-manager \
+	firewall-manager \
 	dhcp-manager \
 	ip6-manager \
 	supplicant-manager \
@@ -11,7 +12,6 @@ SUBDIRS= \
 	dnsmasq-manager \
 	modem-manager \
 	bluez-manager \
-	firewall-manager \
 	wifi \
 	settings
 
@@ -29,13 +29,13 @@ INCLUDES = -I${top_srcdir} \
            -I${top_srcdir}/src/logging \
            -I${top_srcdir}/src/dns-manager \
            -I${top_srcdir}/src/vpn-manager \
+           -I$(top_srcdir)/src/firewall-manager \
            -I${top_srcdir}/src/dhcp-manager \
            -I${top_srcdir}/src/ip6-manager \
            -I${top_srcdir}/src/supplicant-manager \
            -I${top_srcdir}/src/dnsmasq-manager \
            -I${top_srcdir}/src/modem-manager \
            -I$(top_srcdir)/src/bluez-manager \
-           -I$(top_srcdir)/src/firewall-manager \
            -I$(top_srcdir)/src/settings \
            -I$(top_srcdir)/src/wifi \
            -I${top_srcdir}/libnm-util \
@@ -298,6 +298,7 @@ NetworkManager_LDADD = \
 	./logging/libnm-logging.la \
 	./dns-manager/libdns-manager.la \
 	./vpn-manager/libvpn-manager.la \
+	./firewall-manager/libfirewall-manager.la \
 	./dhcp-manager/libdhcp-manager.la \
 	./ip6-manager/libip6-manager.la \
 	./supplicant-manager/libsupplicant-manager.la \
@@ -306,7 +307,6 @@ NetworkManager_LDADD = \
 	./modem-manager/libmodem-manager.la \
 	./bluez-manager/libbluez-manager.la \
 	./wifi/libwifi-utils.la \
-	./firewall-manager/libfirewall-manager.la \
 	./settings/libsettings.la \
 	./backends/libnmbackend.la \
 	$(top_builddir)/libnm-util/libnm-util.la \
diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am
index ce34c41..4ef0185 100644
--- a/src/dhcp-manager/Makefile.am
+++ b/src/dhcp-manager/Makefile.am
@@ -7,6 +7,7 @@ INCLUDES = \
 	-I${top_srcdir}/src/generated \
 	-I${top_builddir}/src/generated \
 	-I${top_srcdir}/src/logging \
+	-I${top_srcdir}/src/firewall-manager \
 	-I${top_srcdir}/libnm-util \
 	-I${top_builddir}/libnm-util \
 	-I${top_srcdir}/src
@@ -58,6 +59,7 @@ libdhcp_manager_la_CPPFLAGS = \
 
 libdhcp_manager_la_LIBADD = \
 	$(top_builddir)/src/logging/libnm-logging.la \
+	$(top_builddir)/src/firewall-manager/libfirewall-manager.la \
 	$(builddir)/libdhcp-dhclient.la \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS)
diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c
index 1af1b16..e483a7a 100644
--- a/src/dhcp-manager/nm-dhcp-manager.c
+++ b/src/dhcp-manager/nm-dhcp-manager.c
@@ -43,6 +43,7 @@
 #include "nm-hostname-provider.h"
 #include "nm-dbus-glib-types.h"
 #include "nm-glib-compat.h"
+#include "nm-firewall-manager.h"
 
 GQuark
 nm_dhcp_manager_error_quark (void)
@@ -72,6 +73,7 @@ typedef struct {
 	GHashTable *        clients;
 	DBusGProxy *        proxy;
 	NMHostnameProvider *hostname_provider;
+	NMFirewallManager  *fw_mgr;
 } NMDHCPManagerPrivate;
 
 
@@ -338,6 +340,8 @@ nm_dhcp_manager_new (const char *client, GError **error)
 	                             singleton,
 	                             NULL);
 
+	priv->fw_mgr = nm_firewall_manager_get();
+
 	return singleton;
 }
 
@@ -385,6 +389,7 @@ static NMDHCPClient *
 client_start (NMDHCPManager *self,
               const char *iface,
               const char *uuid,
+              const char *zone,
               gboolean ipv6,
               NMSettingIP4Config *s_ip4,
               NMSettingIP6Config *s_ip6,
@@ -424,8 +429,16 @@ client_start (NMDHCPManager *self,
 	g_return_val_if_fail (client != NULL, NULL);
 	add_client (self, client);
 
-	if (ipv6)
+	if (ipv6) {
+		/*
+		 * Tell firewall to allow dhcpv6-client service for the given zone prior
+		 * to starting dhcpv6 client. We don't need to wait for the response
+		 * because dhcp client keeps sending Solicit messages until it gets the
+		 * response (i.e. until firewall opens the port).
+		 */
+		nm_firewall_manager_allow_dhcpv6_client(priv->fw_mgr, zone);
 		success = nm_dhcp_client_start_ip6 (client, s_ip6, dhcp_anycast_addr, hostname, info_only);
+	}
 	else
 		success = nm_dhcp_client_start_ip4 (client, s_ip4, dhcp_anycast_addr, hostname);
 
@@ -483,7 +496,7 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self,
 		}
 	}
 
-	client = client_start (self, iface, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE);
+	client = client_start (self, iface, uuid, NULL, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE);
 
 	return client;
 }
@@ -493,12 +506,13 @@ NMDHCPClient *
 nm_dhcp_manager_start_ip6 (NMDHCPManager *self,
                            const char *iface,
                            const char *uuid,
+                           const char *zone,
                            NMSettingIP6Config *s_ip6,
                            guint32 timeout,
                            guint8 *dhcp_anycast_addr,
                            gboolean info_only)
 {
-	return client_start (self, iface, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, NULL, info_only);
+	return client_start (self, iface, uuid, zone, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, NULL, info_only);
 }
 
 static void
@@ -616,6 +630,8 @@ finalize (GObject *object)
 		g_object_unref (priv->proxy);
 	if (priv->dbus_mgr)
 		g_object_unref (priv->dbus_mgr);
+	if (priv->fw_mgr)
+		g_object_unref (priv->fw_mgr);
 
 	G_OBJECT_CLASS (nm_dhcp_manager_parent_class)->finalize (object);
 }
diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h
index a5cfb04..3a189ca 100644
--- a/src/dhcp-manager/nm-dhcp-manager.h
+++ b/src/dhcp-manager/nm-dhcp-manager.h
@@ -75,6 +75,7 @@ NMDHCPClient * nm_dhcp_manager_start_ip4     (NMDHCPManager *manager,
 NMDHCPClient * nm_dhcp_manager_start_ip6     (NMDHCPManager *manager,
                                               const char *iface,
                                               const char *uuid,
+                                              const char *zone,
                                               NMSettingIP6Config *s_ip6,
                                               guint32 timeout,
                                               guint8 *dhcp_anycast_addr,
diff --git a/src/firewall-manager/nm-firewall-manager.c b/src/firewall-manager/nm-firewall-manager.c
index 303c8cd..716e9e3 100644
--- a/src/firewall-manager/nm-firewall-manager.c
+++ b/src/firewall-manager/nm-firewall-manager.c
@@ -176,6 +176,50 @@ nm_firewall_manager_remove_from_zone (NMFirewallManager *self,
 	                                             G_TYPE_INVALID);
 }
 
+static void
+allow_dhcpv6_client_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+	GError *error = NULL;
+	char * zone = NULL;
+
+	if (!dbus_g_proxy_end_call (proxy, call_id, &error,
+	                            G_TYPE_STRING, &zone,
+	                            G_TYPE_INVALID)) {
+		g_assert (error);
+		nm_log_warn (LOGD_FIREWALL, "opening port for dhcpv6 client failed: (%d) %s",
+		             error->code, error->message);
+	}
+
+	g_free (zone);
+	g_clear_error (&error);
+}
+
+
+gpointer
+nm_firewall_manager_allow_dhcpv6_client(NMFirewallManager *self,
+                                        const char *zone)
+{
+	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
+
+	if (priv->running == FALSE) {
+		nm_log_dbg (LOGD_FIREWALL, "opening port for dhcpv6 client skipped (firewall not running)");
+		return NULL;
+	}
+
+	nm_log_dbg (LOGD_FIREWALL, "opening port for dhcpv6 client in zone %s", zone);
+
+	return dbus_g_proxy_begin_call_with_timeout (priv->proxy,
+	                                             "addService",
+	                                             allow_dhcpv6_client_cb,
+	                                             NULL,
+	                                             (GDestroyNotify) NULL,
+	                                             10000,      /* timeout */
+	                                             G_TYPE_STRING, zone ? zone : "",
+	                                             G_TYPE_STRING, "dhcpv6-client",
+	                                             G_TYPE_UINT, 0,
+	                                             G_TYPE_INVALID);
+}
+
 void nm_firewall_manager_cancel_call (NMFirewallManager *self, gpointer call)
 {
 	g_return_if_fail (self != NULL);
diff --git a/src/firewall-manager/nm-firewall-manager.h b/src/firewall-manager/nm-firewall-manager.h
index 113b78e..f4a55b4 100644
--- a/src/firewall-manager/nm-firewall-manager.h
+++ b/src/firewall-manager/nm-firewall-manager.h
@@ -70,6 +70,8 @@ gpointer nm_firewall_manager_add_or_change_zone (NMFirewallManager *mgr,
 gpointer nm_firewall_manager_remove_from_zone (NMFirewallManager *mgr,
                                                const char *iface,
                                                const char *zone);
+gpointer nm_firewall_manager_allow_dhcpv6_client (NMFirewallManager *self,
+                                                  const char *zone);
 
 void nm_firewall_manager_cancel_call (NMFirewallManager *mgr, gpointer fw_call);
 
diff --git a/src/main.c b/src/main.c
index 4a21959..5c68fa3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -596,6 +596,13 @@ main (int argc, char *argv[])
 		goto done;
 	}
 
+	/* Initialize Firewall manager */
+	fw_mgr = nm_firewall_manager_get ();
+	if (!fw_mgr) {
+		nm_log_err (LOGD_CORE, "failed to start the Firewall manager: %s.", error->message);
+		goto done;
+	}
+
 	/* Initialize DHCP manager */
 	dhcp_mgr = nm_dhcp_manager_new (nm_config_get_dhcp_client (config), &error);
 	if (!dhcp_mgr) {
@@ -605,13 +612,6 @@ main (int argc, char *argv[])
 
 	nm_dhcp_manager_set_hostname_provider (dhcp_mgr, NM_HOSTNAME_PROVIDER (manager));
 
-	/* Initialize Firewall manager */
-	fw_mgr = nm_firewall_manager_get ();
-	if (!fw_mgr) {
-		nm_log_err (LOGD_CORE, "failed to start the Firewall manager: %s.", error->message);
-		goto done;
-	}
-
 	/* Start our DBus service */
 	if (!nm_dbus_manager_start_service (dbus_mgr)) {
 		nm_log_err (LOGD_CORE, "failed to start the dbus service.");
diff --git a/src/nm-device.c b/src/nm-device.c
index 089f5f7..b3ca742 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -1889,6 +1889,7 @@ dhcp6_start (NMDevice *self,
 {
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
+	NMSettingConnection *s_con = NULL;
 	guint8 *anycast = NULL;
 	const char *ip_iface;
 	const struct in6_addr dest = { { { 0xFF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
@@ -1928,9 +1929,11 @@ dhcp6_start (NMDevice *self,
 	}
 
 	ip_iface = nm_device_get_ip_iface (self);
+	s_con = nm_connection_get_setting_connection (connection);
 	priv->dhcp6_client = nm_dhcp_manager_start_ip6 (priv->dhcp_manager,
 	                                                ip_iface,
 	                                                nm_connection_get_uuid (connection),
+	                                                nm_setting_connection_get_zone(s_con),
 	                                                nm_connection_get_setting_ip6_config (connection),
 	                                                priv->dhcp_timeout,
 	                                                anycast,
-- 
1.7.7.6



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]