Merge remote branch 'origin/master' into rm-userset
This commit is contained in:
@@ -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)) {
|
||||
|
28
configure.ac
28
configure.ac
@@ -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)
|
||||
|
@@ -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);
|
||||
|
2350
po/sr@latin.po
2350
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
|
@@ -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) \
|
||||
|
64
src/backends/NetworkManagerExherbo.c
Normal file
64
src/backends/NetworkManagerExherbo.c
Normal 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");
|
||||
}
|
||||
}
|
||||
|
@@ -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];
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
*/
|
||||
|
@@ -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 */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
|
||||
/* For dhcpcd */
|
||||
{ "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)
|
||||
test_dhclient_invalid_classless_routes_3 (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";
|
||||
static Option data[] = {
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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-dhclient-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-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 Option gw_in_classless_routes[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
|
||||
/* For dhcpcd */
|
||||
{ "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)
|
||||
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 }
|
||||
};
|
||||
|
||||
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-3", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"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 void
|
||||
test_dhclient_gw_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";
|
||||
static Option data[] = {
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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-dhclient-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-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);
|
||||
|
||||
/* 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");
|
||||
/* Gateway */
|
||||
ip4_test_gateway ("dhcp-dhclient-classless-gateway", ip4_config, expected_gateway);
|
||||
|
||||
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");
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
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");
|
||||
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 }
|
||||
};
|
||||
|
||||
/* 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");
|
||||
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-gateway", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"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);
|
||||
|
||||
/* 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);
|
||||
|
@@ -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"
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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."
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
97
system-settings/plugins/keyfile/utils.c
Normal file
97
system-settings/plugins/keyfile/utils.c
Normal 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;
|
||||
}
|
||||
|
30
system-settings/plugins/keyfile/utils.h
Normal file
30
system-settings/plugins/keyfile/utils.h
Normal 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_ */
|
||||
|
@@ -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 = \
|
||||
|
Reference in New Issue
Block a user