2008-06-09 Dan Williams <dcbw@redhat.com>

* src/dnsmasq-manager/nm-dnsmasq-manager.c
	  src/dnsmasq-manager/nm-dnsmasq-manager.h
		- (create_dm_cmd_line): use the IP4 address of the ip4-config to
			calculate the addresses passed to dnsmasq instead of hard-coding
			them

	* src/nm-device.c
		- (nm_device_new_ip4_shared_config): be somewhat dynamic when choosing
			IP addresses for shared connections to guard against shared
			connection address collisions
		- (real_act_stage4_get_ip4_config): handle possible NULL ip4-configs on
			error conditions
		- (nm_device_activate_stage5_ip_config_commit): pass ip4-config to
			the dnsmasq manager



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3738 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-06-10 02:52:33 +00:00
parent da3296b0ec
commit fb468f7b62
4 changed files with 129 additions and 15 deletions

View file

@ -1,3 +1,20 @@
2008-06-09 Dan Williams <dcbw@redhat.com>
* src/dnsmasq-manager/nm-dnsmasq-manager.c
src/dnsmasq-manager/nm-dnsmasq-manager.h
- (create_dm_cmd_line): use the IP4 address of the ip4-config to
calculate the addresses passed to dnsmasq instead of hard-coding
them
* src/nm-device.c
- (nm_device_new_ip4_shared_config): be somewhat dynamic when choosing
IP addresses for shared connections to guard against shared
connection address collisions
- (real_act_stage4_get_ip4_config): handle possible NULL ip4-configs on
error conditions
- (nm_device_activate_stage5_ip_config_commit): pass ip4-config to
the dnsmasq manager
2008-06-09 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerPolicy.c

View file

@ -225,11 +225,17 @@ dm_watch_cb (GPid pid, gint status, gpointer user_data)
}
static NMCmdLine *
create_dm_cmd_line (const char *iface, const char *pidfile, GError **error)
create_dm_cmd_line (const char *iface,
NMIP4Config *ip4_config,
const char *pidfile,
GError **error)
{
const char *dm_binary;
NMCmdLine *cmd;
char *s;
GString *s;
const NMSettingIP4Address *tmp;
struct in_addr addr;
char buf[INET_ADDRSTRLEN + 1];
dm_binary = nm_find_dnsmasq ();
if (!dm_binary) {
@ -238,24 +244,68 @@ create_dm_cmd_line (const char *iface, const char *pidfile, GError **error)
return NULL;
}
/* Find the IP4 address to use */
tmp = nm_ip4_config_get_address (ip4_config, 0);
/* Create dnsmasq command line */
cmd = nm_cmd_line_new ();
nm_cmd_line_add_string (cmd, dm_binary);
nm_cmd_line_add_string (cmd, "--no-hosts");
nm_cmd_line_add_string (cmd, "--keep-in-foreground");
nm_cmd_line_add_string (cmd, "--listen-address=10.42.43.1");
nm_cmd_line_add_string (cmd, "--bind-interfaces");
nm_cmd_line_add_string (cmd, "--no-poll");
nm_cmd_line_add_string (cmd, "--dhcp-range=10.42.43.10,10.42.43.100,60m");
s = g_string_new ("--listen-address=");
addr.s_addr = tmp->address;
if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
nm_warning ("%s: error converting IP4 address 0x%X",
__func__, ntohl (addr.s_addr));
goto error;
}
g_string_append (s, buf);
nm_cmd_line_add_string (cmd, s->str);
g_string_free (s, TRUE);
s = g_string_new ("--dhcp-range=");
/* Add start of address range */
addr.s_addr = tmp->address + ntohl (9);
if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
nm_warning ("%s: error converting IP4 address 0x%X",
__func__, ntohl (addr.s_addr));
goto error;
}
g_string_append (s, buf);
g_string_append_c (s, ',');
/* Add end of address range */
addr.s_addr = tmp->address + ntohl (99);
if (!inet_ntop (AF_INET, &addr, &buf[0], INET_ADDRSTRLEN)) {
nm_warning ("%s: error converting IP4 address 0x%X",
__func__, ntohl (addr.s_addr));
goto error;
}
g_string_append (s, buf);
g_string_append (s, ",60m");
nm_cmd_line_add_string (cmd, s->str);
g_string_free (s, TRUE);
nm_cmd_line_add_string (cmd, "--dhcp-option=option:router,0.0.0.0");
nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50");
s = g_strdup_printf ("--pid-file=%s", pidfile);
nm_cmd_line_add_string (cmd, s);
g_free (s);
s = g_string_new ("--pid-file=");
g_string_append (s, pidfile);
nm_cmd_line_add_string (cmd, s->str);
g_string_free (s, TRUE);
return cmd;
error:
nm_cmd_line_destroy (cmd);
return NULL;
}
static void
@ -300,7 +350,9 @@ out:
}
gboolean
nm_dnsmasq_manager_start (NMDnsMasqManager *manager, GError **error)
nm_dnsmasq_manager_start (NMDnsMasqManager *manager,
NMIP4Config *ip4_config,
GError **error)
{
NMDnsMasqManagerPrivate *priv;
NMCmdLine *dm_cmd;
@ -315,7 +367,7 @@ nm_dnsmasq_manager_start (NMDnsMasqManager *manager, GError **error)
kill_existing_for_iface (priv->iface, priv->pidfile);
dm_cmd = create_dm_cmd_line (priv->iface, priv->pidfile, error);
dm_cmd = create_dm_cmd_line (priv->iface, ip4_config, priv->pidfile, error);
if (!dm_cmd)
return FALSE;

View file

@ -6,6 +6,8 @@
#include <glib/gtypes.h>
#include <glib-object.h>
#include "nm-ip4-config.h"
#define NM_TYPE_DNSMASQ_MANAGER (nm_dnsmasq_manager_get_type ())
#define NM_DNSMASQ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DNSMASQ_MANAGER, NMDnsMasqManager))
#define NM_DNSMASQ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DNSMASQ_MANAGER, NMDnsMasqManagerClass))
@ -35,7 +37,9 @@ GType nm_dnsmasq_manager_get_type (void);
NMDnsMasqManager *nm_dnsmasq_manager_new (const char *iface);
gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, GError **error);
gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager,
NMIP4Config *ip4_config,
GError **error);
void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager);

View file

@ -653,20 +653,58 @@ nm_device_new_ip4_autoip_config (NMDevice *self)
return config;
}
static GHashTable *shared_ips = NULL;
static void
release_shared_ip (gpointer data)
{
g_hash_table_remove (shared_ips, data);
}
static guint32
reserve_shared_ip (void)
{
guint32 start = (guint32) ntohl (0x0a2a2b01); /* 10.42.43.1 */
guint32 count = 0;
while (g_hash_table_lookup (shared_ips, (gpointer) (start + count))) {
count += ntohl (0x100);
if (count > ntohl (0xFE00)) {
nm_warning ("%s: ran out of shared IP addresses!", __func__);
return 0;
}
}
g_hash_table_insert (shared_ips, (gpointer) (start + count), GUINT_TO_POINTER (TRUE));
return start + count;
}
static NMIP4Config *
nm_device_new_ip4_shared_config (NMDevice *self)
{
NMIP4Config *config = NULL;
NMSettingIP4Address *addr;
guint32 tmp_addr;
g_return_val_if_fail (self != NULL, NULL);
if (G_UNLIKELY (shared_ips == NULL))
shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
tmp_addr = reserve_shared_ip ();
if (!tmp_addr)
return NULL;
config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address));
addr->address = (guint32) ntohl (0x0a2a2b01); /* 10.42.43.1 */
addr->address = tmp_addr;
addr->netmask = (guint32) ntohl (0xFFFFFF00); /* 255.255.255.0 */
nm_ip4_config_take_address (config, addr);
/* Remove the address lock when the object gets disposed */
g_object_set_data_full (G_OBJECT (config), "shared-ip",
GUINT_TO_POINTER (addr->address), release_shared_ip);
return config;
}
@ -690,7 +728,8 @@ real_act_stage4_get_ip4_config (NMDevice *self,
if (nm_device_get_use_dhcp (self)) {
*config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
nm_device_get_iface (self));
nm_utils_merge_ip4_config (*config, s_ip4);
if (*config)
nm_utils_merge_ip4_config (*config, s_ip4);
} else {
g_assert (s_ip4);
@ -698,10 +737,12 @@ real_act_stage4_get_ip4_config (NMDevice *self,
*config = nm_device_new_ip4_autoip_config (self);
} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
*config = nm_ip4_config_new ();
nm_utils_merge_ip4_config (*config, s_ip4);
if (*config)
nm_utils_merge_ip4_config (*config, s_ip4);
} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
*config = nm_device_new_ip4_shared_config (self);
priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
if (*config)
priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
}
}
@ -895,7 +936,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
if (s_ip4 && !strcmp (s_ip4->method, "shared")) {
GError *error = NULL;
if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, &error)) {
if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) {
nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
g_error_free (error);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);