Merge remote branch 'origin/master' into rm-userset

This commit is contained in:
Dan Williams
2010-11-16 18:08:48 -06:00
28 changed files with 6427 additions and 2031 deletions

View File

@@ -489,6 +489,10 @@ nm_dispatcher_action (Handler *h,
if (!d->persist)
d->quit_timeout = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
/* Hostname changes don't require a device nor contain a connection */
if (!strcmp (action, "hostname"))
goto dispatch;
connection = nm_connection_new_from_hash (connection_hash, error);
if (connection) {
NMSettingConnection *s_con;
@@ -506,10 +510,6 @@ nm_dispatcher_action (Handler *h,
*error = NULL;
}
/* Hostname changes don't require a device */
if (!strcmp (action, "hostname"))
goto dispatch;
/* interface name */
value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE);
if (!value || !G_VALUE_HOLDS_STRING (value)) {

View File

@@ -1,6 +1,6 @@
AC_PREREQ(2.52)
AC_INIT(NetworkManager, 0.8.1, dcbw@redhat.com, NetworkManager)
AC_INIT(NetworkManager, 0.8.990, dcbw@redhat.com, NetworkManager)
AM_INIT_AUTOMAKE([1.9 subdir-objects tar-ustar no-dist-gzip dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])
AM_MAINTAINER_MODE
@@ -84,7 +84,7 @@ dnl Make sha1.c happy on big endian systems
dnl
AC_C_BIGENDIAN
AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, suse, gentoo, debian, arch, slackware, paldo, mandriva, pardus or linexa]))
AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, suse, gentoo, debian, arch, slackware, paldo, mandriva, pardus, linexa or exherbo]))
if test "z$with_distro" = "z"; then
AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat")
AC_CHECK_FILE(/etc/SuSE-release,with_distro="suse")
@@ -97,6 +97,7 @@ if test "z$with_distro" = "z"; then
AC_CHECK_FILE(/etc/mandriva-release,with_distro="mandriva")
AC_CHECK_FILE(/etc/pardus-release,with_distro="pardus")
AC_CHECK_FILE(/etc/linexa-release,with_distro="linexa")
AC_CHECK_FILE(/etc/exherbo-release,with_distro="exherbo")
if test "z$with_distro" = "z"; then
with_distro=`lsb_release -is`
fi
@@ -108,7 +109,7 @@ if test "z$with_distro" = "z"; then
exit 1
else
case $with_distro in
redhat|suse|gentoo|debian|slackware|arch|paldo|frugalware|mandriva|pardus|linexa) ;;
redhat|suse|gentoo|debian|slackware|arch|paldo|frugalware|mandriva|pardus|linexa|exherbo) ;;
*)
echo "Your distribution (${with_distro}) is not yet supported! (patches welcome)"
exit 1
@@ -171,6 +172,11 @@ if test x"$with_distro" = xlinexa; then
AC_DEFINE(TARGET_LINEXA, 1, [Define if you have linexa])
fi
AM_CONDITIONAL(TARGET_EXHERBO, test x"$with_distro" = xexherbo)
if test x"$with_distro" = xexherbo; then
AC_DEFINE(TARGET_EXHERBO, 1, [Define if you have Exherbo])
fi
dnl
dnl Distribution version string
dnl
@@ -288,6 +294,20 @@ with_nss=no
with_gnutls=no
if test x"$ac_crypto" = xnss; then
PKG_CHECK_MODULES(NSS, [nss >= 3.11])
# Work around a pkg-config bug (fdo #29801) where exists != usable
AC_PATH_PROG(PKGCONFIG_PATH, pkg-config, no)
if test x"$PKGCONFIG_PATH" = xno; then
AC_MSG_ERROR([pkgconfig required but not found])
else
FOO=`$PKGCONFIG_PATH --cflags --libs nss`
if test x"$?" != "x0"; then
AC_MSG_ERROR([No usable NSS found])
fi
fi
AC_SUBST(NSS_CFLAGS)
AC_SUBST(NSS_LIBS)
AC_DEFINE(HAVE_NSS, 1, [Define if you have NSS])
with_nss=yes
elif test x"$ac_crypto" = xgnutls; then
@@ -304,7 +324,7 @@ elif test x"$ac_crypto" = xgnutls; then
with_gnutls=yes
fi
else
AC_MSG_ERROR([Please choose either 'nss' or 'gnutls' for certificate and key operations])
AC_MSG_ERROR([Please choose either 'nss' or 'gnutls' for certificate and crypto operations])
fi
AM_CONDITIONAL(WITH_NSS, test x"$with_nss" != xno)
AM_CONDITIONAL(WITH_GNUTLS, test x"$with_gnutls" != xno)

View File

@@ -344,6 +344,7 @@ set_property (GObject *object, guint prop_id,
{
NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object);
const char *str;
char *tmp;
switch (prop_id) {
case PROP_NUMBER:
@@ -360,11 +361,17 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_APN:
g_free (priv->apn);
priv->apn = g_strstrip (g_value_dup_string (value));
priv->apn = NULL;
tmp = g_value_dup_string (value);
if (tmp)
priv->apn = g_strstrip (tmp);
break;
case PROP_NETWORK_ID:
g_free (priv->network_id);
priv->network_id = g_strstrip (g_value_dup_string (value));
priv->network_id = NULL;
tmp = g_value_dup_string (value);
if (tmp)
priv->network_id = g_strstrip (tmp);
break;
case PROP_NETWORK_TYPE:
priv->network_type = g_value_get_int (value);

1766
po/cs.po

File diff suppressed because it is too large Load Diff

553
po/lt.po

File diff suppressed because it is too large Load Diff

2350
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -277,8 +277,10 @@ EXTRA_DIST = \
$(NetworkManager_DATA)
rundir=$(localstatedir)/run/NetworkManager
statedir=$(localstatedir)/lib/NetworkManager
install-data-hook:
$(mkinstalldirs) -m 0700 $(DESTDIR)$(rundir)
$(mkinstalldirs) -m 0700 $(DESTDIR)$(statedir)
CLEANFILES = $(BUILT_SOURCES)

View File

@@ -57,6 +57,10 @@ if TARGET_LINEXA
libnmbackend_la_SOURCES += NetworkManagerLinexa.c
endif
if TARGET_EXHERBO
libnmbackend_la_SOURCES += NetworkManagerExherbo.c
endif
libnmbackend_la_LIBADD += \
$(top_builddir)/src/logging/libnm-logging.la \
$(DBUS_LIBS) \

View File

@@ -0,0 +1,64 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
* Dan Willemsen <dan@willemsen.us>
* Robert Paskowitz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2004 Red Hat, Inc.
* (C) Copyright 2004 Dan Willemsen
* (C) Copyright 2004 Robert Paskowitz
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "NetworkManagerGeneric.h"
#include "nm-system.h"
#include "NetworkManagerUtils.h"
#include "nm-logging.h"
/*
* nm_system_enable_loopback
*
* Bring up the loopback interface
*
*/
void nm_system_enable_loopback (void)
{
nm_generic_enable_loopback ();
}
/*
* nm_system_update_dns
*
* Make glibc/nscd aware of any changes to the resolv.conf file by
* restarting nscd. Only restart if already running.
*
*/
void nm_system_update_dns (void)
{
if (g_file_test ("/usr/sbin/nscd", G_FILE_TEST_IS_EXECUTABLE)) {
nm_log_info (LOGD_DNS, "Clearing nscd hosts cache.");
nm_spawn_process ("/usr/sbin/nscd -i hosts");
}
}

View File

@@ -18,6 +18,7 @@
*/
#include <config.h>
#include <ctype.h>
#include <glib.h>
#include <string.h>
#include <sys/types.h>
@@ -647,6 +648,243 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self,
/********************************************/
static gboolean
ip4_process_dhcpcd_rfc3442_routes (const char *str,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
char **routes, **r;
gboolean have_routes = FALSE;
routes = g_strsplit (str, " ", 0);
if (g_strv_length (routes) == 0)
goto out;
if ((g_strv_length (routes) % 2) != 0) {
nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid");
goto out;
}
for (r = routes; *r; r += 2) {
char *slash;
NMIP4Route *route;
int rt_cidr = 32;
struct in_addr rt_addr;
struct in_addr rt_route;
slash = strchr(*r, '/');
if (slash) {
*slash = '\0';
errno = 0;
rt_cidr = strtol (slash + 1, NULL, 10);
if ((errno == EINVAL) || (errno == ERANGE)) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1);
continue;
}
}
if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r);
continue;
}
if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
continue;
}
have_routes = TRUE;
if (rt_cidr == 0 && rt_addr.s_addr == 0) {
/* FIXME: how to handle multiple routers? */
*gwaddr = rt_route.s_addr;
} else {
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
nm_ip4_route_set_prefix (route, rt_cidr);
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
nm_ip4_config_take_route (ip4_config, route);
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
}
}
out:
g_strfreev (routes);
return have_routes;
}
static const char **
process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
{
const char **o = octets;
int addr_len = 0, i = 0;
long int tmp;
NMIP4Route *route;
char *next_hop;
struct in_addr tmp_addr;
if (!*o)
return o; /* no prefix */
tmp = strtol (*o, NULL, 10);
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
return o;
route = nm_ip4_route_new ();
nm_ip4_route_set_prefix (route, (guint32) tmp);
o++;
if (tmp > 0)
addr_len = ((tmp - 1) / 8) + 1;
/* ensure there's at least the address + next hop left */
if (g_strv_length ((char **) o) < addr_len + 4)
goto error;
if (tmp) {
const char *addr[4] = { "0", "0", "0", "0" };
char *str_addr;
for (i = 0; i < addr_len; i++)
addr[i] = *o++;
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) {
g_free (str_addr);
goto error;
}
tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp);
nm_ip4_route_set_dest (route, tmp_addr.s_addr);
}
/* Handle next hop */
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) {
g_free (next_hop);
goto error;
}
nm_ip4_route_set_next_hop (route, tmp_addr.s_addr);
g_free (next_hop);
*out_route = route;
return o + 4; /* advance to past the next hop */
error:
nm_ip4_route_unref (route);
return o;
}
static gboolean
ip4_process_dhclient_rfc3442_routes (const char *str,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
char **octets, **o;
gboolean have_routes = FALSE;
NMIP4Route *route = NULL;
o = octets = g_strsplit_set (str, " .", 0);
if (g_strv_length (octets) < 5) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
goto out;
}
while (*o) {
route = NULL;
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route);
if (!route) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes");
break;
}
have_routes = TRUE;
if (nm_ip4_route_get_prefix (route) == 0) {
/* gateway passed as classless static route */
*gwaddr = nm_ip4_route_get_next_hop (route);
nm_ip4_route_unref (route);
} else {
char addr[INET_ADDRSTRLEN + 1];
char nh[INET_ADDRSTRLEN + 1];
struct in_addr tmp;
/* normal route */
nm_ip4_config_take_route (ip4_config, route);
tmp.s_addr = nm_ip4_route_get_dest (route);
inet_ntop (AF_INET, &tmp, addr, sizeof (addr));
tmp.s_addr = nm_ip4_route_get_next_hop (route);
inet_ntop (AF_INET, &tmp, nh, sizeof (nh));
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
addr, nm_ip4_route_get_prefix (route), nh);
}
}
out:
g_strfreev (octets);
return have_routes;
}
static gboolean
ip4_process_classless_routes (GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
const char *str, *p;
g_return_val_if_fail (options != NULL, FALSE);
g_return_val_if_fail (ip4_config != NULL, FALSE);
*gwaddr = 0;
/* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a
* slightly different format:
*
* option classless-static-routes = array of (destination-descriptor ip-address);
*
* which results in:
*
* 0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6
*
* dhcpcd supports classless static routes natively and uses this same
* option identifier with the following format:
*
* 192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41
*/
str = g_hash_table_lookup (options, "new_classless_static_routes");
/* dhclient doesn't have actual support for rfc3442 classless static routes
* upstream. Thus, people resort to defining the option in dhclient.conf
* and using arbitrary formats like so:
*
* option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
*
* See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html
*/
if (!str)
str = g_hash_table_lookup (options, "new_rfc3442_classless_static_routes");
/* Microsoft version; same as rfc3442 but with a different option # (249) */
if (!str)
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
if (!str || !strlen (str))
return FALSE;
p = str;
while (*p) {
if (!isdigit (*p) && (*p != ' ') && (*p != '.') && (*p != '/')) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
return FALSE;
}
p++;
};
if (strchr (str, '/')) {
/* dhcpcd format */
return ip4_process_dhcpcd_rfc3442_routes (str, ip4_config, gwaddr);
}
return ip4_process_dhclient_rfc3442_routes (str, ip4_config, gwaddr);
}
static void
process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
{
@@ -747,7 +985,6 @@ ip4_options_to_config (NMDHCPClient *self)
NMIP4Address *addr = NULL;
char *str = NULL;
guint32 gwaddr = 0, prefix = 0;
gboolean have_classless = FALSE;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL);
@@ -788,17 +1025,8 @@ ip4_options_to_config (NMDHCPClient *self)
/* Routes: if the server returns classless static routes, we MUST ignore
* the 'static_routes' option.
*/
if (NM_DHCP_CLIENT_GET_CLASS (self)->ip4_process_classless_routes) {
have_classless = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_process_classless_routes (self,
priv->options,
ip4_config,
&gwaddr);
}
if (!have_classless) {
gwaddr = 0; /* Ensure client code doesn't lie */
if (!ip4_process_classless_routes (priv->options, ip4_config, &gwaddr))
process_classful_routes (priv->options, ip4_config);
}
if (gwaddr) {
char buf[INET_ADDRSTRLEN + 1];

View File

@@ -76,15 +76,6 @@ typedef struct {
/* Methods */
/* Given the options table, extract any classless routes, add them to
* the IP4 config and return TRUE if any existed. If a gateway was sent
* as a classless route return that in out_gwaddr.
*/
gboolean (*ip4_process_classless_routes) (NMDHCPClient *self,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *out_gwaddr);
GPid (*ip4_start) (NMDHCPClient *self,
NMSettingIP4Config *s_ip4,
guint8 *anycast_addr,

View File

@@ -635,136 +635,6 @@ real_stop (NMDHCPClient *client)
remove (priv->pid_file);
}
static const char **
process_rfc3442_route (const char **octets, NMIP4Route **out_route)
{
const char **o = octets;
int addr_len = 0, i = 0;
long int tmp;
NMIP4Route *route;
char *next_hop;
struct in_addr tmp_addr;
if (!*o)
return o; /* no prefix */
tmp = strtol (*o, NULL, 10);
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
return o;
route = nm_ip4_route_new ();
nm_ip4_route_set_prefix (route, (guint32) tmp);
o++;
if (tmp > 0)
addr_len = ((tmp - 1) / 8) + 1;
/* ensure there's at least the address + next hop left */
if (g_strv_length ((char **) o) < addr_len + 4)
goto error;
if (tmp) {
const char *addr[4] = { "0", "0", "0", "0" };
char *str_addr;
for (i = 0; i < addr_len; i++)
addr[i] = *o++;
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) {
g_free (str_addr);
goto error;
}
tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp);
nm_ip4_route_set_dest (route, tmp_addr.s_addr);
}
/* Handle next hop */
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) {
g_free (next_hop);
goto error;
}
nm_ip4_route_set_next_hop (route, tmp_addr.s_addr);
g_free (next_hop);
*out_route = route;
return o + 4; /* advance to past the next hop */
error:
nm_ip4_route_unref (route);
return o;
}
static gboolean
real_ip4_process_classless_routes (NMDHCPClient *client,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
const char *str;
char **octets, **o;
gboolean have_routes = FALSE;
NMIP4Route *route = NULL;
/* dhclient doesn't have actual support for rfc3442 classless static routes
* upstream. Thus, people resort to defining the option in dhclient.conf
* and using arbitrary formats like so:
*
* option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
*
* See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html
*/
str = g_hash_table_lookup (options, "new_rfc3442_classless_static_routes");
/* Microsoft version; same as rfc3442 but with a different option # (249) */
if (!str)
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
if (!str || !strlen (str))
return FALSE;
o = octets = g_strsplit (str, " ", 0);
if (g_strv_length (octets) < 5) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
goto out;
}
while (*o) {
route = NULL;
o = (char **) process_rfc3442_route ((const char **) o, &route);
if (!route) {
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes");
break;
}
have_routes = TRUE;
if (nm_ip4_route_get_prefix (route) == 0) {
/* gateway passed as classless static route */
*gwaddr = nm_ip4_route_get_next_hop (route);
nm_ip4_route_unref (route);
} else {
char addr[INET_ADDRSTRLEN + 1];
char nh[INET_ADDRSTRLEN + 1];
struct in_addr tmp;
/* normal route */
nm_ip4_config_take_route (ip4_config, route);
tmp.s_addr = nm_ip4_route_get_dest (route);
inet_ntop (AF_INET, &tmp, addr, sizeof (addr));
tmp.s_addr = nm_ip4_route_get_next_hop (route);
inet_ntop (AF_INET, &tmp, nh, sizeof (nh));
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
addr, nm_ip4_route_get_prefix (route), nh);
}
}
out:
g_strfreev (octets);
return have_routes;
}
/***************************************************/
static void
@@ -801,6 +671,5 @@ nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class)
client_class->ip4_start = real_ip4_start;
client_class->ip6_start = real_ip6_start;
client_class->stop = real_stop;
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
}

View File

@@ -179,83 +179,6 @@ real_stop (NMDHCPClient *client)
remove (priv->pid_file);
}
static gboolean
real_ip4_process_classless_routes (NMDHCPClient *client,
GHashTable *options,
NMIP4Config *ip4_config,
guint32 *gwaddr)
{
const char *str;
char **routes, **r;
gboolean have_routes = FALSE;
/* Classless static routes over-ride any static routes and routers
* provided. We should also check for MS classless static routes as
* they implemented the draft RFC using their own code.
*/
str = g_hash_table_lookup (options, "new_classless_static_routes");
if (!str)
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
if (!str || !strlen (str))
return FALSE;
routes = g_strsplit (str, " ", 0);
if (g_strv_length (routes) == 0)
goto out;
if ((g_strv_length (routes) % 2) != 0) {
nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid");
goto out;
}
for (r = routes; *r; r += 2) {
char *slash;
NMIP4Route *route;
int rt_cidr = 32;
struct in_addr rt_addr;
struct in_addr rt_route;
slash = strchr(*r, '/');
if (slash) {
*slash = '\0';
errno = 0;
rt_cidr = strtol (slash + 1, NULL, 10);
if ((errno == EINVAL) || (errno == ERANGE)) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1);
continue;
}
}
if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r);
continue;
}
if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
continue;
}
have_routes = TRUE;
if (rt_cidr == 0 && rt_addr.s_addr == 0) {
/* FIXME: how to handle multiple routers? */
*gwaddr = rt_addr.s_addr;
} else {
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
nm_ip4_route_set_prefix (route, rt_cidr);
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
nm_ip4_config_take_route (ip4_config, route);
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
}
}
out:
g_strfreev (routes);
return have_routes;
}
/***************************************************/
static void
@@ -290,6 +213,5 @@ nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class)
client_class->ip4_start = real_ip4_start;
client_class->ip6_start = real_ip6_start;
client_class->stop = real_stop;
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
}

View File

@@ -228,6 +228,8 @@ typedef struct {
guint fw_monitor_id;
guint fw_changed_id;
guint timestamp_update_id;
gboolean disposed;
} NMManagerPrivate;
@@ -435,6 +437,45 @@ nm_manager_update_state (NMManager *manager)
}
}
static void
ignore_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer user_data)
{
}
static void
update_active_connection_timestamp (NMManager *manager, NMDevice *device)
{
NMActRequest *req;
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingsConnectionInterface *connection_interface;
NMManagerPrivate *priv;
g_return_if_fail (NM_IS_DEVICE (device));
priv = NM_MANAGER_GET_PRIVATE (manager);
req = nm_device_get_act_request (device);
if (!req)
return;
connection = nm_act_request_get_connection (req);
g_assert (connection);
if (nm_connection_get_scope (connection) != NM_CONNECTION_SCOPE_SYSTEM)
return;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL);
if (nm_setting_connection_get_read_only (s_con))
return;
connection_interface = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (priv->sys_settings),
nm_connection_get_path (connection));
nm_settings_connection_interface_update (connection_interface, ignore_cb, NULL);
}
static void
manager_device_state_changed (NMDevice *device,
NMDeviceState new_state,
@@ -457,6 +498,9 @@ manager_device_state_changed (NMDevice *device,
}
nm_manager_update_state (manager);
if (new_state == NM_DEVICE_STATE_ACTIVATED)
update_active_connection_timestamp (manager, device);
}
/* Removes a device from a device list; returns the start of the new device list */
@@ -2005,7 +2049,7 @@ nm_manager_activate_connection (NMManager *manager,
if (state < NM_DEVICE_STATE_DISCONNECTED) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE,
"%s", "Device not managed by NetworkManager");
"%s", "Device not managed by NetworkManager or unavailable");
return NULL;
}
@@ -3166,6 +3210,11 @@ dispose (GObject *object)
g_object_unref (priv->fw_monitor);
}
if (priv->timestamp_update_id) {
g_source_remove (priv->timestamp_update_id);
priv->timestamp_update_id = 0;
}
G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
}
@@ -3278,6 +3327,28 @@ get_property (GObject *object, guint prop_id,
}
}
static gboolean
periodic_update_active_connection_timestamps (gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
GPtrArray *active;
int i;
active = get_active_connections (manager, NULL);
for (i = 0; i < active->len; i++) {
const char *active_path = g_ptr_array_index (active, i);
NMActRequest *req;
NMDevice *device = NULL;
req = nm_manager_get_act_request_by_path (manager, active_path, &device);
if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
update_active_connection_timestamp (manager, device);
}
return TRUE;
}
static void
nm_manager_init (NMManager *manager)
{
@@ -3406,6 +3477,9 @@ nm_manager_init (NMManager *manager)
nm_log_warn (LOGD_CORE, "failed to monitor kernel firmware directory '%s'.",
KERNEL_FIRMWARE_DIR);
}
/* Update timestamps in active connections */
priv->timestamp_update_id = g_timeout_add_seconds (300, (GSourceFunc) periodic_update_active_connection_timestamps, manager);
}
static void

View File

@@ -69,6 +69,8 @@ struct NMPolicy {
};
#define INVALID_TAG "invalid"
#define RETRIES_TAG "autoconnect-retries"
#define RETRIES_DEFAULT 4
static const char *
get_connection_id (NMConnection *connection)
@@ -717,6 +719,18 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
update_system_hostname (policy, policy->default_device4, policy->default_device6);
}
static void
set_connection_auto_retries (NMConnection *connection, guint retries)
{
g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GUINT_TO_POINTER (retries));
}
static guint32
get_connection_auto_retries (NMConnection *connection)
{
return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG));
}
typedef struct {
NMPolicy *policy;
NMDevice *device;
@@ -744,17 +758,26 @@ auto_activate_device (gpointer user_data)
connections = nm_settings_get_connections (policy->settings);
/* Remove connections that are in the invalid list. */
/* Remove connections that have INVALID_TAG and shouldn't be retried any more. */
iter = connections;
while (iter) {
NMConnection *iter_connection = NM_CONNECTION (iter->data);
GSList *next = g_slist_next (iter);
if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) {
guint retries = get_connection_auto_retries (iter_connection);
if (retries == 0) {
connections = g_slist_remove_link (connections, iter);
g_object_unref (iter_connection);
g_slist_free (iter);
} else if (retries > 0)
set_connection_auto_retries (iter_connection, retries - 1);
} else {
/* Set the initial # of retries for auto-connection */
set_connection_auto_retries (iter_connection, RETRIES_DEFAULT);
}
iter = next;
}
@@ -902,6 +925,7 @@ device_state_changed (NMDevice *device,
*/
if (connection && IS_ACTIVATING_STATE (old_state)) {
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
if (get_connection_auto_retries (connection) == 0)
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
nm_connection_clear_secrets (connection);
}
@@ -912,6 +936,9 @@ device_state_changed (NMDevice *device,
/* Clear the invalid tag on the connection */
g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
/* Reset RETRIES_TAG to number from the setting */
set_connection_auto_retries (connection, RETRIES_DEFAULT);
/* And clear secrets so they will always be requested from the
* settings service when the next connection is made.
*/

View File

@@ -250,149 +250,274 @@ test_wins_options (const char *client)
g_hash_table_destroy (options);
}
static Option classless_routes_options[] = {
/* For dhclient */
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" },
/* For dhcpcd */
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" },
{ NULL, NULL }
};
static void
ip4_test_route (const char *test,
NMIP4Config *ip4_config,
guint route_num,
const char *expected_dest,
const char *expected_gw,
guint expected_prefix)
{
NMIP4Route *route;
struct in_addr tmp;
route = nm_ip4_config_get_route (ip4_config, route_num);
ASSERT (inet_pton (AF_INET, expected_dest, &tmp) > 0,
test, "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
test, "unexpected route %d destination", route_num + 1);
ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0,
test, "couldn't convert expected route next hop %d",
route_num + 1);
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
test, "unexpected route %d next hop", route_num + 1);
ASSERT (nm_ip4_route_get_prefix (route) == expected_prefix,
test, "unexpected route %d prefix", route_num + 1);
ASSERT (nm_ip4_route_get_metric (route) == 0,
test, "unexpected route %d metric", route_num + 1);
}
static void
test_classless_static_routes (const char *client)
ip4_test_gateway (const char *test,
NMIP4Config *ip4_config,
const char *expected_gw)
{
NMIP4Address *addr;
struct in_addr tmp;
ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1,
test, "unexpected number of IP addresses");
addr = nm_ip4_config_get_address (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0,
test, "couldn't convert expected IP gateway");
ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr,
test, "unexpected IP gateway");
}
static void
test_classless_static_routes_1 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
NMIP4Route *route;
struct in_addr tmp;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_route2_dest = "10.0.0.0";
const char *expected_route2_gw = "10.17.66.41";
static Option data[] = {
/* dhclient custom format */
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (classless_routes_options, options);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-rfc3442", "failed to parse DHCP4 options");
"dhcp-classless-1", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-rfc3442", "unexpected number of IP routes");
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-rfc3442", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-rfc3442", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 24,
"dhcp-rfc3442", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442", "unexpected route #1 metric");
/* Route #2 */
route = nm_ip4_config_get_route (ip4_config, 1);
ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0,
"dhcp-rfc3442", "couldn't convert expected route destination #2");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442", "unexpected route #2 destination");
ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0,
"dhcp-rfc3442", "couldn't convert expected route next hop #2");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442", "unexpected route #2 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 8,
"dhcp-rfc3442", "unexpected route #2 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442", "unexpected route #2 metric");
"dhcp-classless-1", "unexpected number of IP routes");
ip4_test_route ("dhcp-classless-1", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
ip4_test_route ("dhcp-classless-1", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 8);
g_hash_table_destroy (options);
}
static Option invalid_classless_routes1[] = {
/* For dhclient */
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" },
/* For dhcpcd */
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" },
{ NULL, NULL }
};
static void
test_invalid_classless_routes1 (const char *client)
test_classless_static_routes_2 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
NMIP4Route *route;
struct in_addr tmp;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_route2_dest = "10.0.0.0";
const char *expected_route2_gw = "10.17.66.41";
static Option data[] = {
/* dhcpcd format */
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes1, options);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-1", "failed to parse DHCP4 options");
"dhcp-classless-2", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-rfc3442-invalid-1", "unexpected number of IP routes");
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-rfc3442-invalid-1", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-1", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-rfc3442-invalid-1", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-1", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 24,
"dhcp-rfc3442-invalid-1", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442-invalid-1", "unexpected route #1 metric");
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-classless-2", "unexpected number of IP routes");
ip4_test_route ("dhcp-classless-2", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
ip4_test_route ("dhcp-classless-2", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 8);
g_hash_table_destroy (options);
}
static Option invalid_classless_routes2[] = {
/* For dhclient */
{ "new_rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" },
/* For dhcpcd */
{ "new_classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" },
{ NULL, NULL }
};
static void
test_invalid_classless_routes2 (const char *client)
test_fedora_dhclient_classless_static_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "129.210.177.128";
const char *expected_route1_gw = "192.168.0.113";
const char *expected_route2_dest = "2.0.0.0";
const char *expected_route2_gw = "10.34.255.6";
const char *expected_gateway = "192.168.0.113";
static Option data[] = {
/* Fedora dhclient format */
{ "new_classless_static_routes", "0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-fedora-dhclient-classless", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-fedora-dhclient-classless", "unexpected number of IP routes");
ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 25);
ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 7);
/* Gateway */
ip4_test_gateway ("dhcp-fedora-dhclient-classless", ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
static void
test_dhclient_invalid_classless_routes_1 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static Option data[] = {
/* dhclient format */
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-dhclient-classless-invalid-1", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-dhclient-classless-invalid-1", "unexpected number of IP routes");
ip4_test_route ("dhcp-dhclient-classless-invalid-1", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_1 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
NMIP4Route *route;
struct in_addr tmp;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static Option data[] = {
/* dhcpcd format */
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes2, options);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-2", "failed to parse DHCP4 options");
"dhcp-dhcpcd-classless-invalid-1", "failed to parse DHCP4 options");
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-dhcpcdp-classless-invalid-1", "unexpected number of routes");
ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 32);
ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static void
test_dhclient_invalid_classless_routes_2 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static Option data[] = {
{ "new_rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-dhclient-classless-invalid-2", "failed to parse DHCP4 options");
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
*/
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-dhclient-classless-invalid-2", "unexpected number of routes");
ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 32);
ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_2 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "10.1.1.5";
const char *expected_route1_gw = "10.1.1.1";
const char *expected_route2_dest = "100.99.88.56";
const char *expected_route2_gw = "10.1.1.1";
static Option data[] = {
{ "new_classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" },
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-dhcpcd-classless-invalid-2", "failed to parse DHCP4 options");
/* Test falling back to old-style static routes if the classless static
* routes are invalid.
@@ -400,150 +525,131 @@ test_invalid_classless_routes2 (const char *client)
/* Routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
"dhcp-rfc3442-invalid-2", "unexpected number of routes");
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-rfc3442-invalid-2", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-2", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-rfc3442-invalid-2", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-2", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 32,
"dhcp-rfc3442-invalid-2", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442-invalid-2", "unexpected route #1 metric");
/* Route #2 */
route = nm_ip4_config_get_route (ip4_config, 1);
ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0,
"dhcp-rfc3442-invalid-2", "couldn't convert expected route destination #2");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-2", "unexpected route #2 destination");
ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0,
"dhcp-rfc3442-invalid-2", "couldn't convert expected route next hop #2");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-2", "unexpected route #2 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 32,
"dhcp-rfc3442-invalid-2", "unexpected route #2 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442-invalid-2", "unexpected route #2 metric");
"dhcp-dhcpcd-classless-invalid-2", "unexpected number of routes");
ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 32);
ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 1,
expected_route2_dest, expected_route2_gw, 32);
g_hash_table_destroy (options);
}
static Option invalid_classless_routes3[] = {
/* For dhclient */
static void
test_dhclient_invalid_classless_routes_3 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static Option data[] = {
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
/* For dhcpcd */
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-dhclient-classless-invalid-3", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-dhclient-classless-invalid-3", "unexpected number of IP routes");
ip4_test_route ("dhcp-dhclient-classless-invalid-3", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_invalid_classless_routes_3 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
static Option data[] = {
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" },
{ NULL, NULL }
};
static void
test_invalid_classless_routes3 (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
NMIP4Route *route;
struct in_addr tmp;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
options = fill_table (generic_options, NULL);
options = fill_table (invalid_classless_routes3, options);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-rfc3442-invalid-3", "failed to parse DHCP4 options");
"dhcp-dhcpcd-classless-invalid-3", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-rfc3442-invalid-3", "unexpected number of IP routes");
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-rfc3442-invalid-3", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-3", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-rfc3442-invalid-3", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442-invalid-3", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 24,
"dhcp-rfc3442-invalid-3", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442-invalid-3", "unexpected route #1 metric");
"dhcp-dhcpcd-classless-invalid-3", "unexpected number of IP routes");
ip4_test_route ("dhcp-dhcpcd-classless-invalid-3", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
g_hash_table_destroy (options);
}
static Option gw_in_classless_routes[] = {
/* For dhclient */
static void
test_dhclient_gw_in_classless_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_gateway = "192.2.3.4";
static Option data[] = {
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
/* For dhcpcd */
{ NULL, NULL }
};
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-dhclient-classless-gateway", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-dhclient-classless-gateway", "unexpected number of IP routes");
ip4_test_route ("dhcp-dhclient-classless-gateway", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
/* Gateway */
ip4_test_gateway ("dhcp-dhclient-classless-gateway", ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
static void
test_dhcpcd_gw_in_classless_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_gateway = "192.2.3.4";
static Option data[] = {
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" },
{ NULL, NULL }
};
static void
test_gateway_in_classless_routes (const char *client)
{
GHashTable *options;
NMIP4Config *ip4_config;
NMIP4Address *addr;
NMIP4Route *route;
struct in_addr tmp;
const char *expected_route1_dest = "192.168.10.0";
const char *expected_route1_gw = "192.168.1.1";
const char *expected_gateway = "192.2.3.4";
options = fill_table (generic_options, NULL);
options = fill_table (gw_in_classless_routes, options);
options = fill_table (data, options);
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
ASSERT (ip4_config != NULL,
"dhcp-rfc3442-gateway", "failed to parse DHCP4 options");
"dhcp-dhcpcd-classless-gateway", "failed to parse DHCP4 options");
/* IP4 routes */
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
"dhcp-rfc3442-gateway", "unexpected number of IP routes");
"dhcp-dhcpcd-classless-gateway", "unexpected number of IP routes");
ip4_test_route ("dhcp-dhcpcd-classless-gateway", ip4_config, 0,
expected_route1_dest, expected_route1_gw, 24);
/* Route #1 */
route = nm_ip4_config_get_route (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
"dhcp-rfc3442-gateway", "couldn't convert expected route destination #1");
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
"dhcp-rfc3442-gateway", "unexpected route #1 destination");
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
"dhcp-rfc3442-gateway", "couldn't convert expected route next hop #1");
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
"dhcp-rfc3442-gateway", "unexpected route #1 next hop");
ASSERT (nm_ip4_route_get_prefix (route) == 24,
"dhcp-rfc3442-gateway", "unexpected route #1 prefix");
ASSERT (nm_ip4_route_get_metric (route) == 0,
"dhcp-rfc3442-gateway", "unexpected route #1 metric");
/* Address */
ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1,
"dhcp-rfc3442-gateway", "unexpected number of IP addresses");
addr = nm_ip4_config_get_address (ip4_config, 0);
ASSERT (inet_pton (AF_INET, expected_gateway, &tmp) > 0,
"dhcp-rfc3442-gateway", "couldn't convert expected IP gateway");
ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr,
"dhcp-rfc3442-gateway", "unexpected IP gateway");
/* Gateway */
ip4_test_gateway ("dhcp-dhcpcd-classless-gateway", ip4_config, expected_gateway);
g_hash_table_destroy (options);
}
@@ -694,11 +800,17 @@ int main (int argc, char **argv)
test_generic_options (client);
test_wins_options (client);
test_classless_static_routes (client);
test_invalid_classless_routes1 (client);
test_invalid_classless_routes2 (client);
test_invalid_classless_routes3 (client);
test_gateway_in_classless_routes (client);
test_classless_static_routes_1 (client);
test_classless_static_routes_2 (client);
test_fedora_dhclient_classless_static_routes (client);
test_dhclient_invalid_classless_routes_1 (client);
test_dhcpcd_invalid_classless_routes_1 (client);
test_dhclient_invalid_classless_routes_2 (client);
test_dhcpcd_invalid_classless_routes_2 (client);
test_dhclient_invalid_classless_routes_3 (client);
test_dhcpcd_invalid_classless_routes_3 (client);
test_dhclient_gw_in_classless_routes (client);
test_dhcpcd_gw_in_classless_routes (client);
test_escaped_domain_searches (client);
test_invalid_escaped_domain_searches (client);
test_ip4_missing_prefix (client, "192.168.1.10", 24);

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2008 - 2009 Red Hat, Inc.
* (C) Copyright 2008 - 2010 Red Hat, Inc.
*/
#ifndef __COMMON_H__
@@ -39,7 +39,7 @@
#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts"
#define IFCFG_PLUGIN_NAME "ifcfg-rh"
#define IFCFG_PLUGIN_INFO "(c) 2007 - 2008 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
#define IFCFG_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
#define TYPE_ETHERNET "Ethernet"
#define TYPE_WIRELESS "Wireless"

View File

@@ -269,9 +269,19 @@ connection_new_or_changed (SCPluginIfcfg *self,
return;
}
/* Successfully read connection */
/* Successfully read connection changes */
old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing));
/* When the connections are the same, nothing is done */
if (nm_connection_compare (NM_CONNECTION (connection),
NM_CONNECTION (new),
NM_SETTING_COMPARE_FLAG_EXACT)) {
g_object_unref (new);
return;
}
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection));
new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
if (new_unmanaged) {

View File

@@ -29,8 +29,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dbus/dbus-glib.h>
#include <nm-utils.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
@@ -9490,11 +9488,9 @@ test_read_vlan_interface (void)
int main (int argc, char **argv)
{
GError *error = NULL;
DBusGConnection *bus;
char *base;
g_type_init ();
bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
if (!nm_utils_init (&error))
FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2008 - 2009 Red Hat, Inc.
* (C) Copyright 2008 - 2010 Red Hat, Inc.
*/
#include <glib.h>
@@ -115,6 +115,27 @@ utils_hexstr2bin (const char *hex, size_t len)
/* End from hostap */
/*
* Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when
* installing packages.
*
* Implementation taken from upstart.
*/
static gboolean
check_rpm_temp_suffix (const char *path)
{
const char *ptr;
g_return_val_if_fail (path != NULL, FALSE);
/* Matches *;[a-fA-F0-9]{8}; used by rpm */
ptr = strrchr (path, ';');
if (ptr && (strspn (ptr + 1, "abcdefABCDEF0123456789") == 8)
&& (! ptr[9]))
return TRUE;
return FALSE;
}
static gboolean
check_suffix (const char *base, const char *tag)
{
@@ -162,7 +183,8 @@ utils_should_ignore_file (const char *filename, gboolean only_ifcfg)
&& !check_suffix (base, REJ_TAG)
&& !check_suffix (base, RPMNEW_TAG)
&& !check_suffix (base, AUGNEW_TAG)
&& !check_suffix (base, AUGTMP_TAG))
&& !check_suffix (base, AUGTMP_TAG)
&& !check_rpm_temp_suffix (base))
ignore = FALSE;
g_free (base);

View File

@@ -16,6 +16,8 @@ libkeyfile_io_la_SOURCES = \
writer.c \
writer.h \
errors.c \
utils.c \
utils.h \
common.h
libkeyfile_io_la_CPPFLAGS = \
@@ -49,6 +51,8 @@ libnm_settings_plugin_keyfile_la_LIBADD = \
$(DBUS_LIBS) \
$(GIO_LIBS)
keyfiledir=$(sysconfdir)/NetworkManager/system-connections
install-data-hook:
$(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir)

View File

@@ -23,6 +23,9 @@
#include <glib.h>
#define SWP_TAG ".swp"
#define SWPX_TAG ".swpx"
#define KEYFILE_PLUGIN_NAME "keyfile"
#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."

View File

@@ -39,6 +39,7 @@
#include "nm-keyfile-connection.h"
#include "writer.h"
#include "common.h"
#include "utils.h"
#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
@@ -125,6 +126,9 @@ read_connections (NMSystemConfigInterface *config)
NMSysconfigConnection *connection;
char *full_path;
if (utils_should_ignore_file (item))
continue;
full_path = g_build_filename (KEYFILE_DIR, item, NULL);
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item);
@@ -219,6 +223,11 @@ dir_changed (GFileMonitor *monitor,
GError *error = NULL;
full_path = g_file_get_path (file);
if (utils_should_ignore_file (full_path)) {
g_free (full_path);
return;
}
connection = g_hash_table_lookup (priv->hash, full_path);
switch (event_type) {
@@ -230,15 +239,18 @@ dir_changed (GFileMonitor *monitor,
break;
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path);
if (connection) {
/* Update */
NMKeyfileConnection *tmp;
tmp = nm_keyfile_connection_new (full_path, NULL, &error);
if (tmp) {
if (!nm_connection_compare (NM_CONNECTION (connection),
NM_CONNECTION (tmp),
NM_SETTING_COMPARE_FLAG_EXACT)) {
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name);
update_connection_settings (connection, tmp);
}
g_object_unref (tmp);
} else {
/* Error; remove the connection */
@@ -248,6 +260,8 @@ dir_changed (GFileMonitor *monitor,
remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path);
}
} else {
PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name);
/* New */
connection = nm_keyfile_connection_new (full_path, NULL, &error);
if (connection) {

View File

@@ -27,8 +27,6 @@
#include <arpa/inet.h>
#include <sys/socket.h>
#include <dbus/dbus-glib.h>
#include <nm-utils.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
@@ -1989,11 +1987,9 @@ test_write_gsm_connection (void)
int main (int argc, char **argv)
{
GError *error = NULL;
DBusGConnection *bus;
char *base;
g_type_init ();
bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
if (!nm_utils_init (&error))
FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
@@ -2022,7 +2018,6 @@ int main (int argc, char **argv)
base = g_path_get_basename (argv[0]);
fprintf (stdout, "%s: SUCCESS\n", base);
g_free (base);
dbus_g_connection_unref (bus);
return 0;
}

View File

@@ -0,0 +1,97 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "utils.h"
static const char temp_letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/*
* Check '.[a-zA-Z0-9]{6}' file suffix used for temporary files by g_file_set_contents() (mkstemp()).
*/
static gboolean
check_mkstemp_suffix (const char *path)
{
const char *ptr;
g_return_val_if_fail (path != NULL, FALSE);
/* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */
ptr = strrchr (path, '.');
if (ptr && (strspn (ptr + 1, temp_letters) == 6) && (! ptr[7]))
return TRUE;
return FALSE;
}
static gboolean
check_prefix (const char *base, const char *tag)
{
int len, tag_len;
g_return_val_if_fail (base != NULL, TRUE);
g_return_val_if_fail (tag != NULL, TRUE);
len = strlen (base);
tag_len = strlen (tag);
if ((len > tag_len) && !strncasecmp (base, tag, tag_len))
return TRUE;
return FALSE;
}
static gboolean
check_suffix (const char *base, const char *tag)
{
int len, tag_len;
g_return_val_if_fail (base != NULL, TRUE);
g_return_val_if_fail (tag != NULL, TRUE);
len = strlen (base);
tag_len = strlen (tag);
if ((len > tag_len) && !strcasecmp (base + len - tag_len, tag))
return TRUE;
return FALSE;
}
gboolean
utils_should_ignore_file (const char *filename)
{
char *base;
gboolean ignore = FALSE;
g_return_val_if_fail (filename != NULL, TRUE);
base = g_path_get_basename (filename);
g_return_val_if_fail (base != NULL, TRUE);
/* Ignore files with certain patterns */
if ( (check_prefix (base, ".") && check_suffix (base, SWP_TAG)) /* vim temporary files: .filename.swp */
|| (check_prefix (base, ".") && check_suffix (base, SWPX_TAG)) /* vim temporary files: .filename.swpx */
|| check_mkstemp_suffix (base)) /* temporary files created by mkstemp() */
ignore = TRUE;
g_free (base);
return ignore;
}

View File

@@ -0,0 +1,30 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2010 Red Hat, Inc.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
#include <glib.h>
#include "common.h"
gboolean utils_should_ignore_file (const char *filename);
#endif /* _UTILS_H_ */

View File

@@ -10,9 +10,9 @@ AM_CPPFLAGS = \
-DNM_RUN_DIR=\"$(rundir)\" \
-DDATADIR=\"$(datadir)\"
bin_PROGRAMS = nm-tool
bin_PROGRAMS = nm-tool nm-online
noinst_PROGRAMS = nm-online libnm-glib-test
noinst_PROGRAMS = libnm-glib-test
nm_tool_SOURCES = nm-tool.c
nm_tool_LDADD = \