[PATCH v0.7 3/6] core: allow devices to specify a DHCP anycast address



Relevant only for OLPC at this point; the mesh device uses it to
target DHCP requests at a pre-defined mesh portal anycast address.
---
 src/dhcp-manager/nm-dhcp-dhclient.c |   23 +++++++++++++++++++----
 src/dhcp-manager/nm-dhcp-dhcpcd.c   |    3 ++-
 src/dhcp-manager/nm-dhcp-manager.c  |    5 +++--
 src/dhcp-manager/nm-dhcp-manager.h  |    6 ++++--
 src/nm-device.c                     |   32 +++++++++++++++++++++++++++++---
 src/nm-device.h                     |    1 +
 6 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
index 81cecb6..691e129 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient.c
@@ -84,6 +84,7 @@ get_leasefile_for_iface (const char * iface, const char *uuid)
 static gboolean
 merge_dhclient_config (NMDHCPDevice *device,
                        NMSettingIP4Config *s_ip4,
+                       guint8 *anycast_addr,
                        const char *contents,
                        const char *orig,
                        GError **error)
@@ -162,6 +163,17 @@ merge_dhclient_config (NMDHCPDevice *device,
 			g_string_append_printf (new_contents, DHCP_HOSTNAME_FORMAT "\n", tmp);
 	}
 
+	if (anycast_addr) {
+		g_string_append_printf (new_contents, "interface \"%s\" {\n"
+		                        " initial-interval 1; \n"
+		                        " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n"
+		                        "}\n",
+		                        device->iface,
+		                        anycast_addr[0], anycast_addr[1],
+		                        anycast_addr[2], anycast_addr[3],
+		                        anycast_addr[4], anycast_addr[5]);
+	}
+
 	if (g_file_set_contents (device->conf_file, new_contents->str, -1, error))
 		success = TRUE;
 
@@ -176,7 +188,9 @@ merge_dhclient_config (NMDHCPDevice *device,
  * config file along with the NM options.
  */
 static gboolean
-create_dhclient_config (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
+create_dhclient_config (NMDHCPDevice *device,
+                        NMSettingIP4Config *s_ip4,
+                        guint8 *dhcp_anycast_addr)
 {
 	char *orig = NULL, *contents = NULL;
 	GError *error = NULL;
@@ -216,7 +230,7 @@ create_dhclient_config (NMDHCPDevice *device, NMSettingIP4Config *s_ip4)
 
 out:
 	error = NULL;
-	if (merge_dhclient_config (device, s_ip4, contents, orig, &error))
+	if (merge_dhclient_config (device, s_ip4, dhcp_anycast_addr, contents, orig, &error))
 		success = TRUE;
 	else {
 		nm_warning ("%s: error creating dhclient configuration: %s",
@@ -242,7 +256,8 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED)
 GPid
 nm_dhcp_client_start (NMDHCPDevice *device,
                       const char *uuid,
-                      NMSettingIP4Config *s_ip4)
+                      NMSettingIP4Config *s_ip4,
+                      guint8 *dhcp_anycast_addr)
 {
 	GPtrArray *dhclient_argv = NULL;
 	GPid pid = 0;
@@ -266,7 +281,7 @@ nm_dhcp_client_start (NMDHCPDevice *device,
 		goto out;
 	}
 
-	if (!create_dhclient_config (device, s_ip4))
+	if (!create_dhclient_config (device, s_ip4, dhcp_anycast_addr))
 		goto out;
 
 	/* Kill any existing dhclient bound to this interface */
diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c
index 05db9dd..a6ce8d2 100644
--- a/src/dhcp-manager/nm-dhcp-dhcpcd.c
+++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c
@@ -62,7 +62,8 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED)
 GPid
 nm_dhcp_client_start (NMDHCPDevice *device,
                       const char *uuid,
-                      NMSettingIP4Config *s_ip4)
+                      NMSettingIP4Config *s_ip4,
+                      guint8 *dhcp_anycast_addr)
 {
 	GPtrArray *argv = NULL;
 	GPid pid = 0;
diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c
index c5a6509..523a3ee 100644
--- a/src/dhcp-manager/nm-dhcp-manager.c
+++ b/src/dhcp-manager/nm-dhcp-manager.c
@@ -578,7 +578,8 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
                                    const char *iface,
                                    const char *uuid,
                                    NMSettingIP4Config *s_ip4,
-                                   guint32 timeout)
+                                   guint32 timeout,
+                                   guint8 *dhcp_anycast_addr)
 {
 	NMDHCPManagerPrivate *priv;
 	NMDHCPDevice *device;
@@ -603,7 +604,7 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
 	nm_info ("Activation (%s) Beginning DHCP transaction (timeout in %d seconds)",
 	         iface, timeout);
 
-	device->pid = nm_dhcp_client_start (device, uuid, s_ip4);
+	device->pid = nm_dhcp_client_start (device, uuid, s_ip4, dhcp_anycast_addr);
 	if (device->pid == 0)
 		return FALSE;
 
diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h
index 79964a9..2c5514e 100644
--- a/src/dhcp-manager/nm-dhcp-manager.h
+++ b/src/dhcp-manager/nm-dhcp-manager.h
@@ -91,7 +91,8 @@ gboolean       nm_dhcp_manager_begin_transaction    (NMDHCPManager *manager,
                                                      const char *iface,
                                                      const char *uuid,
                                                      NMSettingIP4Config *s_ip4,
-                                                     guint32 timeout);
+                                                     guint32 timeout,
+                                                     guint8 *dhcp_anycast_addr);
 void           nm_dhcp_manager_cancel_transaction   (NMDHCPManager *manager,
                                                      const char *iface);
 NMIP4Config *  nm_dhcp_manager_get_ip4_config       (NMDHCPManager *manager, const char *iface);
@@ -105,7 +106,8 @@ gboolean       nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self,
 /* The following are implemented by the DHCP client backends */
 GPid           nm_dhcp_client_start                 (NMDHCPDevice *device,
                                                      const char *uuid,
-                                                     NMSettingIP4Config *s_ip4);
+                                                     NMSettingIP4Config *s_ip4,
+                                                     guint8 *anycast_addr);
 void           nm_dhcp_client_stop                  (NMDHCPDevice *device, pid_t pid);
 
 gboolean       nm_dhcp_client_process_classless_routes (GHashTable *options,
diff --git a/src/nm-device.c b/src/nm-device.c
index c55a9e5..046e795 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -94,6 +94,7 @@ struct _NMDevicePrivate
 	guint32             dhcp_timeout;
 	gulong              dhcp_state_sigid;
 	gulong              dhcp_timeout_sigid;
+	GByteArray *        dhcp_anycast_address;
 	NMDHCP4Config *     dhcp4_config;
 
 	/* dnsmasq stuff for shared connections */
@@ -891,6 +892,10 @@ real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason)
 	if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
 		NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
 		gboolean success;
+		guint8 *anycast = NULL;
+
+		if (priv->dhcp_anycast_address)
+			anycast = priv->dhcp_anycast_address->data;
 
 		/* Begin a DHCP transaction on the interface */
 		nm_device_set_use_dhcp (self, TRUE);
@@ -898,7 +903,7 @@ real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason)
 		/* DHCP manager will cancel any transaction already in progress and we do not
 		   want to cancel this activation if we get "down" state from that. */
 		g_signal_handler_block (priv->dhcp_manager, priv->dhcp_state_sigid);
-		success = nm_dhcp_manager_begin_transaction (priv->dhcp_manager, ip_iface, uuid, s_ip4, priv->dhcp_timeout);
+		success = nm_dhcp_manager_begin_transaction (priv->dhcp_manager, ip_iface, uuid, s_ip4, priv->dhcp_timeout, anycast);
 		g_signal_handler_unblock (priv->dhcp_manager, priv->dhcp_state_sigid);
 
 		if (success) {
@@ -2217,6 +2222,8 @@ nm_device_finalize (GObject *object)
 	g_free (self->priv->iface);
 	g_free (self->priv->ip_iface);
 	g_free (self->priv->driver);
+	if (self->priv->dhcp_anycast_address)
+		g_byte_array_free (self->priv->dhcp_anycast_address, TRUE);
 
 	G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
 }
@@ -2514,11 +2521,30 @@ nm_device_set_managed (NMDevice *device,
 }
 
 void
-nm_device_set_dhcp_timeout (NMDevice *device,
-                            guint32 timeout)
+nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout)
 {
 	g_return_if_fail (NM_IS_DEVICE (device));
 
 	NM_DEVICE_GET_PRIVATE (device)->dhcp_timeout = timeout;
 }
 
+void
+nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr)
+{
+	NMDevicePrivate *priv;
+
+	g_return_if_fail (NM_IS_DEVICE (device));
+
+	priv = NM_DEVICE_GET_PRIVATE (device);
+
+	if (priv->dhcp_anycast_address) {
+		g_byte_array_free (priv->dhcp_anycast_address, TRUE);
+		priv->dhcp_anycast_address = NULL;
+	}
+
+	if (addr) {
+		priv->dhcp_anycast_address = g_byte_array_sized_new (ETH_ALEN);
+		g_byte_array_append (priv->dhcp_anycast_address, addr, ETH_ALEN);
+	}
+}
+
diff --git a/src/nm-device.h b/src/nm-device.h
index fc394dd..05409b5 100644
--- a/src/nm-device.h
+++ b/src/nm-device.h
@@ -166,6 +166,7 @@ void nm_device_set_managed (NMDevice *device,
                             NMDeviceStateReason reason);
 
 void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout);
+void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr);
 
 G_END_DECLS
 
-- 
1.6.4



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