diff options
author | Daniel Drake <dsd@laptop.org> | 2009-07-15 13:53:49 -0400 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2009-07-15 13:53:49 -0400 |
commit | 3fe8d0eed4c1e2b4c4c2d4454e5ec68d2272d2c3 (patch) | |
tree | ef648d663a558a7e42eaa05eface6719d2b3d398 | |
parent | 0f56957b77b0d86cf4cae3141e70f777cfc8847f (diff) |
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.
-rw-r--r-- | src/dhcp-manager/nm-dhcp-dhclient.c | 23 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-dhcpcd.c | 3 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-manager.c | 5 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-manager.h | 6 | ||||
-rw-r--r-- | src/nm-device.c | 33 | ||||
-rw-r--r-- | src/nm-device.h | 1 |
6 files changed, 59 insertions, 12 deletions
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index e8ce4960e6..f35465976b 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -83,12 +83,13 @@ get_leasefile_for_iface (const char * iface, const char *uuid) #define DHCP_HOSTNAME_TAG "send host-name" #define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager" static gboolean merge_dhclient_config (NMDHCPDevice *device, NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, const char *contents, const char *orig, GError **error) { GString *new_contents; gboolean success = FALSE; @@ -161,12 +162,23 @@ merge_dhclient_config (NMDHCPDevice *device, tmp = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); if (tmp) 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; g_string_free (new_contents, TRUE); return success; } @@ -175,13 +187,15 @@ merge_dhclient_config (NMDHCPDevice *device, * file cannot be used since DHCP transactions can happen in parallel. * Since some distros don't have default per-interface dhclient config files, * read their single config file and merge that into a custom per-interface * 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; gboolean success = FALSE; char *tmp; @@ -215,13 +229,13 @@ create_dhclient_config (NMDHCPDevice *device, NMSettingIP4Config *s_ip4) g_error_free (error); goto out; } 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", device->iface, error->message); g_error_free (error); } @@ -241,13 +255,14 @@ 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; GError *error = NULL; char *pid_contents = NULL; @@ -265,13 +280,13 @@ nm_dhcp_client_start (NMDHCPDevice *device, device->lease_file = get_leasefile_for_iface (device->iface, uuid); if (!device->lease_file) { nm_warning ("%s: not enough memory for dhclient options.", device->iface); 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 */ if (g_file_get_contents (device->pid_file, &pid_contents, NULL, NULL)) { unsigned long int tmp = strtoul (pid_contents, NULL, 10); diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 05db9dd16f..a6ce8d21e6 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -59,13 +59,14 @@ 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; GError *error = NULL; char *pid_contents = NULL; diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 22368b9677..bdd2695b2a 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -584,13 +584,14 @@ static void dhcp_watch_cb (GPid pid, gint status, gpointer user_data) 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) { NMDHCPManagerPrivate *priv; NMDHCPDevice *device; NMSettingIP4Config *setting; g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), FALSE); @@ -626,13 +627,13 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, if (timeout == 0) timeout = NM_DHCP_TIMEOUT; nm_info ("Activation (%s) Beginning DHCP transaction (timeout in %d seconds)", iface, timeout); - device->pid = nm_dhcp_client_start (device, uuid, setting); + device->pid = nm_dhcp_client_start (device, uuid, setting, dhcp_anycast_addr); if (setting) g_object_unref (setting); 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 f8737cbff0..6880a2336c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -92,13 +92,14 @@ void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager, NMHostnameProvider *provider); 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); NMDHCPState nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, const char *iface); gboolean nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self, @@ -106,13 +107,14 @@ gboolean nm_dhcp_manager_foreach_dhcp4_option (NMDHCPManager *self, GHFunc func, gpointer user_data); /* 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, NMIP4Config *ip4_config, guint32 *gwaddr); diff --git a/src/nm-device.c b/src/nm-device.c index 401d529af6..db71eaea1d 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -89,12 +89,13 @@ typedef struct { /* IP configuration info */ NMIP4Config * ip4_config; /* Config from DHCP, PPP, or system config files */ NMDHCPManager * dhcp_manager; guint32 dhcp_timeout; gulong dhcp_state_sigid; gulong dhcp_timeout_sigid; + GByteArray * dhcp_anycast_address; NMDHCP4Config * dhcp4_config; /* dnsmasq stuff for shared connections */ NMDnsMasqManager *dnsmasq_manager; gulong dnsmasq_state_id; @@ -891,20 +892,24 @@ real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason) if (s_ip4) method = nm_setting_ip4_config_get_method (s_ip4); 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); /* 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) { /* DHCP devices will be notified by the DHCP manager when * stuff happens. */ @@ -2215,12 +2220,14 @@ finalize (GObject *object) g_free (priv->udi); g_free (priv->iface); g_free (priv->ip_iface); g_free (priv->driver); g_free (priv->type_desc); + if (priv->dhcp_anycast_address) + g_byte_array_free (priv->dhcp_anycast_address, TRUE); G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); } static void @@ -2536,14 +2543,34 @@ nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs) return NM_DEVICE_GET_CLASS (self)->spec_match_list (self, specs); return FALSE; } 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 39003938a8..45a3f9efcb 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -160,10 +160,11 @@ NMDeviceState nm_device_get_state (NMDevice *device); gboolean nm_device_get_managed (NMDevice *device); void nm_device_set_managed (NMDevice *device, gboolean managed, 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 #endif /* NM_DEVICE_H */ |