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.
This commit is contained in:

committed by
Dan Williams

parent
0f56957b77
commit
3fe8d0eed4
@@ -86,6 +86,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)
|
||||
@@ -164,6 +165,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;
|
||||
|
||||
@@ -178,7 +190,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;
|
||||
@@ -218,7 +232,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",
|
||||
@@ -244,7 +258,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;
|
||||
@@ -268,7 +283,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 */
|
||||
|
@@ -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;
|
||||
|
@@ -587,7 +587,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;
|
||||
@@ -629,7 +630,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, setting);
|
||||
device->pid = nm_dhcp_client_start (device, uuid, setting, dhcp_anycast_addr);
|
||||
|
||||
if (setting)
|
||||
g_object_unref (setting);
|
||||
|
@@ -95,7 +95,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);
|
||||
@@ -109,7 +110,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,
|
||||
|
@@ -92,6 +92,7 @@ typedef struct {
|
||||
guint32 dhcp_timeout;
|
||||
gulong dhcp_state_sigid;
|
||||
gulong dhcp_timeout_sigid;
|
||||
GByteArray * dhcp_anycast_address;
|
||||
NMDHCP4Config * dhcp4_config;
|
||||
|
||||
/* dnsmasq stuff for shared connections */
|
||||
@@ -894,6 +895,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);
|
||||
@@ -901,7 +906,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) {
|
||||
@@ -2218,6 +2223,8 @@ finalize (GObject *object)
|
||||
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);
|
||||
}
|
||||
@@ -2539,11 +2546,31 @@ nm_device_spec_match_list (NMDeviceInterface *device, const GSList *specs)
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -163,6 +163,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
|
||||
|
||||
|
Reference in New Issue
Block a user