mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-06 13:10:29 +01:00
Merge remote branch 'origin/master' into cli-output
This commit is contained in:
commit
688de6d782
86 changed files with 4105 additions and 2191 deletions
|
|
@ -296,7 +296,7 @@ AC_ARG_WITH([pppd-plugin-dir], AS_HELP_STRING([--with-pppd-plugin-dir=DIR], [pat
|
|||
if test -n "$with_pppd_plugin_dir" ; then
|
||||
PPPD_PLUGIN_DIR="$with_pppd_plugin_dir"
|
||||
else
|
||||
PPPD_PLUGIN_DIR="${libdir}/pppd/2.4.4"
|
||||
PPPD_PLUGIN_DIR="${libdir}/pppd/2.4.5"
|
||||
fi
|
||||
AC_SUBST(PPPD_PLUGIN_DIR)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2009 Red Hat, Inc.
|
||||
* (C) Copyright 2009 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -86,7 +86,7 @@ static TypeNameElement name_map[] = {
|
|||
{ "GPtrArray_GArray_guint__", "array of array of uint32" },
|
||||
{ "GPtrArray_GArray_guchar__", "array of byte array" },
|
||||
{ "GHashTable_gchararray+gchararray_", "dict of (string::string)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint__", "array of (byte array, uint32)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint+GArray_guchar___", "array of (byte array, uint32, byte array)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint+GArray_guchar_+guint__", "array of (byte array, uint32, byte array, uint32)" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
EXTRA_DIST = \
|
||||
nm-state.py \
|
||||
add-system-connection.py
|
||||
add-system-connection.py \
|
||||
vpn.py \
|
||||
list-connections.py \
|
||||
show-bssids.py
|
||||
|
||||
|
||||
|
|
|
|||
112
examples/python/list-connections.py
Normal file
112
examples/python/list-connections.py
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#!/bin/env python
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Copyright (C) 2010 Red Hat, Inc.
|
||||
#
|
||||
|
||||
import dbus
|
||||
|
||||
# This example asks both the system settings service and the user settings
|
||||
# service for all configured connections. It also asks for secrets, demonstrating
|
||||
# the mechanisms each settings service uses to prevent unauthorized access to
|
||||
# a user's network passwords
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
|
||||
def merge_secrets(proxy, config, setting_name):
|
||||
try:
|
||||
# returns a dict of dicts mapping name::setting, where setting is a dict
|
||||
# mapping key::value. Each member of the 'setting' dict is a secret
|
||||
secrets = proxy.GetSecrets(setting_name, [], False)
|
||||
|
||||
# Copy the secrets into our connection config
|
||||
for setting in secrets:
|
||||
for key in secrets[setting]:
|
||||
config[setting_name][key] = setting[key]
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
def dict_to_string(d, indent):
|
||||
# Try to trivially translate a dictionary's elements into nice string
|
||||
# formatting.
|
||||
dstr = ""
|
||||
for key in d:
|
||||
val = d[key]
|
||||
str_val = ""
|
||||
add_string = True
|
||||
if type(val) == type(dbus.Array([])):
|
||||
for elt in val:
|
||||
if type(elt) == type(dbus.Byte(1)):
|
||||
str_val += "%s " % int(elt)
|
||||
elif type(elt) == type(dbus.String("")):
|
||||
str_val += "%s" % elt
|
||||
elif type(val) == type(dbus.Dictionary({})):
|
||||
dstr += dict_to_string(val, indent + " ")
|
||||
add_string = False
|
||||
else:
|
||||
str_val = val
|
||||
if add_string:
|
||||
dstr += "%s%s: %s\n" % (indent, key, str_val)
|
||||
return dstr
|
||||
|
||||
def connection_to_string(config):
|
||||
# dump a connection configuration to a the console
|
||||
for setting_name in config:
|
||||
print " Setting: %s" % setting_name
|
||||
print dict_to_string(config[setting_name], " ")
|
||||
print ""
|
||||
|
||||
|
||||
def print_one_services_connections(service_name, desc):
|
||||
# Ask the settings service for the list of connections it provides
|
||||
proxy = bus.get_object(service_name, "/org/freedesktop/NetworkManagerSettings")
|
||||
settings = dbus.Interface(proxy, "org.freedesktop.NetworkManagerSettings")
|
||||
connection_paths = settings.ListConnections()
|
||||
|
||||
print "%s connections --------------------------------------------\n" % desc
|
||||
|
||||
# List each connection's name, UUID, and type
|
||||
for path in connection_paths:
|
||||
con_proxy = bus.get_object(service_name, path)
|
||||
connection = dbus.Interface(con_proxy, "org.freedesktop.NetworkManagerSettings.Connection")
|
||||
config = connection.GetSettings()
|
||||
|
||||
# Now get secrets too; we grab the secrets for each type of connection
|
||||
# (since there isn't a "get all secrets" call because most of the time
|
||||
# you only need 'wifi' secrets or '802.1x' secrets, not everything) and
|
||||
# merge that into the configuration data
|
||||
connection_secrets = dbus.Interface(con_proxy, "org.freedesktop.NetworkManagerSettings.Connection.Secrets")
|
||||
merge_secrets(connection_secrets, config, '802-11-wireless')
|
||||
merge_secrets(connection_secrets, config, '802-11-wireless-security')
|
||||
merge_secrets(connection_secrets, config, '802-1x')
|
||||
merge_secrets(connection_secrets, config, 'gsm')
|
||||
merge_secrets(connection_secrets, config, 'cdma')
|
||||
merge_secrets(connection_secrets, config, 'ppp')
|
||||
|
||||
# Get the details of the 'connection' setting
|
||||
s_con = config['connection']
|
||||
print "name: %s" % s_con['id']
|
||||
print " uuid: %s" % s_con['uuid']
|
||||
print " type: %s" % s_con['type']
|
||||
print " ----------------------------"
|
||||
connection_to_string(config)
|
||||
|
||||
print ""
|
||||
|
||||
# Print out connection information for all connections
|
||||
print_one_services_connections("org.freedesktop.NetworkManagerSystemSettings", "System")
|
||||
print_one_services_connections("org.freedesktop.NetworkManagerUserSettings", "User")
|
||||
|
||||
78
examples/python/show-bssids.py
Normal file
78
examples/python/show-bssids.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/env python
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Copyright (C) 2010 Red Hat, Inc.
|
||||
#
|
||||
|
||||
|
||||
# This example prints out all the AP BSSIDs that all WiFi devices on the
|
||||
# machine can see. Useful for location-based services like Skyhook that
|
||||
# can geolocate you based on the APs you can see.
|
||||
|
||||
import dbus
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
|
||||
# Get a proxy for the base NetworkManager object
|
||||
proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
|
||||
manager = dbus.Interface(proxy, "org.freedesktop.NetworkManager")
|
||||
|
||||
all_aps = []
|
||||
|
||||
print "Associated APs:"
|
||||
|
||||
# Get all network devices
|
||||
devices = manager.GetDevices()
|
||||
for d in devices:
|
||||
dev_proxy = bus.get_object("org.freedesktop.NetworkManager", d)
|
||||
prop_iface = dbus.Interface(dev_proxy, "org.freedesktop.DBus.Properties")
|
||||
|
||||
# Make sure the device is enabled before we try to use it
|
||||
state = prop_iface.Get("org.freedesktop.NetworkManager.Device", "State")
|
||||
if state <= 2:
|
||||
continue
|
||||
|
||||
# Get device's type; we only want wifi devices
|
||||
iface = prop_iface.Get("org.freedesktop.NetworkManager.Device", "Interface")
|
||||
dtype = prop_iface.Get("org.freedesktop.NetworkManager.Device", "DeviceType")
|
||||
if dtype == 2: # WiFi
|
||||
# Get a proxy for the wifi interface
|
||||
wifi_iface = dbus.Interface(dev_proxy, "org.freedesktop.NetworkManager.Device.Wireless")
|
||||
wifi_prop_iface = dbus.Interface(dev_proxy, "org.freedesktop.DBus.Properties")
|
||||
|
||||
# Get the associated AP's object path
|
||||
connected_path = wifi_prop_iface.Get("org.freedesktop.NetworkManager.Device.Wireless", "ActiveAccessPoint")
|
||||
|
||||
# Get all APs the card can see
|
||||
aps = wifi_iface.GetAccessPoints()
|
||||
for path in aps:
|
||||
ap_proxy = bus.get_object("org.freedesktop.NetworkManager", path)
|
||||
ap_prop_iface = dbus.Interface(ap_proxy, "org.freedesktop.DBus.Properties")
|
||||
bssid = ap_prop_iface.Get("org.freedesktop.NetworkManager.AccessPoint", "HwAddress")
|
||||
|
||||
# Cache the BSSID
|
||||
if not bssid in all_aps:
|
||||
all_aps.append(bssid)
|
||||
|
||||
# Print the current AP's BSSID
|
||||
if path == connected_path:
|
||||
print "%s (%s)" % (bssid, iface)
|
||||
|
||||
# and print out all APs the wifi devices can see
|
||||
print"\nFound APs:"
|
||||
for bssid in all_aps:
|
||||
print bssid
|
||||
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
#define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
|
||||
#define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING))
|
||||
|
||||
#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ADDRESS))
|
||||
#define DBUS_TYPE_G_IP6_ROUTE (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ROUTE))
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@
|
|||
<tp:docstring>The state of this active connection.</tp:docstring>
|
||||
</property>
|
||||
<property name="Default" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is the default connection, i.e. whether it currently owns the default route.</tp:docstring>
|
||||
<tp:docstring>Whether this active connection is the default IPv4 connection, i.e. whether it currently owns the default IPv4 route.</tp:docstring>
|
||||
</property>
|
||||
<property name="Default6" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is the default IPv6 connection, i.e. whether it currently owns the default IPv6 route.</tp:docstring>
|
||||
</property>
|
||||
<property name="Vpn" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is also a VPN connection.</tp:docstring>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
|
||||
<interface name="org.freedesktop.NetworkManager.IP6Config">
|
||||
<property name="Addresses" type="a(ayu)" access="read">
|
||||
<tp:docstring>Tuples of IPv6 address/prefix.</tp:docstring>
|
||||
<property name="Addresses" type="a(ayuay)" access="read">
|
||||
<tp:docstring>Tuples of IPv6 address/prefix/gateway.</tp:docstring>
|
||||
</property>
|
||||
<property name="Nameservers" type="aay" access="read">
|
||||
<tp:docstring>The nameservers in use.</tp:docstring>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@
|
|||
<tp:docstring>
|
||||
A combination of logging domains separated by commas (','), or "NONE"
|
||||
to disable logging. Each domain enables logging for operations
|
||||
related to that domain. Available domains are: [NONE, HW, RKILL,
|
||||
related to that domain. Available domains are: [NONE, HW, RFKILL,
|
||||
ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP, WIFI_SCAN, IP4, IP6, AUTOIP4,
|
||||
DNS, VPN, SHARING, SUPPLICANT, USER_SET, SYS_SET, SUSPEND, CORE,
|
||||
DEVICE, OLPC]
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ libnm_glib_la_LIBADD = \
|
|||
$(GUDEV_LIBS)
|
||||
|
||||
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \
|
||||
-version-info "4:1:2"
|
||||
-version-info "4:2:2"
|
||||
|
||||
noinst_PROGRAMS = libnm-glib-test
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ global:
|
|||
nm_access_point_new;
|
||||
nm_active_connection_get_connection;
|
||||
nm_active_connection_get_default;
|
||||
nm_active_connection_get_default6;
|
||||
nm_active_connection_get_devices;
|
||||
nm_active_connection_get_scope;
|
||||
nm_active_connection_get_service_name;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -50,6 +50,7 @@ typedef struct {
|
|||
GPtrArray *devices;
|
||||
NMActiveConnectionState state;
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
} NMActiveConnectionPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -60,6 +61,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -70,6 +72,7 @@ enum {
|
|||
#define DBUS_PROP_DEVICES "Devices"
|
||||
#define DBUS_PROP_STATE "State"
|
||||
#define DBUS_PROP_DEFAULT "Default"
|
||||
#define DBUS_PROP_DEFAULT6 "Default6"
|
||||
|
||||
/**
|
||||
* nm_active_connection_new:
|
||||
|
|
@ -263,10 +266,10 @@ nm_active_connection_get_state (NMActiveConnection *connection)
|
|||
* nm_active_connection_get_default:
|
||||
* @connection: a #NMActiveConnection
|
||||
*
|
||||
* Whether the active connection is the default one (that is, is used for the default route
|
||||
* and DNS information).
|
||||
* Whether the active connection is the default IPv4 one (that is, is used for
|
||||
* the default IPv4 route and DNS information).
|
||||
*
|
||||
* Returns: %TRUE if the active connection is the default one
|
||||
* Returns: %TRUE if the active connection is the default IPv4 connection
|
||||
**/
|
||||
gboolean
|
||||
nm_active_connection_get_default (NMActiveConnection *connection)
|
||||
|
|
@ -278,13 +281,39 @@ nm_active_connection_get_default (NMActiveConnection *connection)
|
|||
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
|
||||
if (!priv->is_default) {
|
||||
priv->is_default = _nm_object_get_boolean_property (NM_OBJECT (connection),
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT);
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT);
|
||||
}
|
||||
|
||||
return priv->is_default;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_active_connection_get_default6:
|
||||
* @connection: a #NMActiveConnection
|
||||
*
|
||||
* Whether the active connection is the default IPv6 one (that is, is used for
|
||||
* the default IPv6 route and DNS information).
|
||||
*
|
||||
* Returns: %TRUE if the active connection is the default IPv6 connection
|
||||
**/
|
||||
gboolean
|
||||
nm_active_connection_get_default6 (NMActiveConnection *connection)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE);
|
||||
|
||||
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
|
||||
if (!priv->is_default6) {
|
||||
priv->is_default6 = _nm_object_get_boolean_property (NM_OBJECT (connection),
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT6);
|
||||
}
|
||||
|
||||
return priv->is_default6;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_active_connection_init (NMActiveConnection *ap)
|
||||
{
|
||||
|
|
@ -350,6 +379,9 @@ get_property (GObject *object,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, nm_active_connection_get_default (self));
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, nm_active_connection_get_default6 (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -392,6 +424,7 @@ register_for_property_changed (NMActiveConnection *connection)
|
|||
{ NM_ACTIVE_CONNECTION_DEVICES, demarshal_devices, &priv->devices },
|
||||
{ NM_ACTIVE_CONNECTION_STATE, _nm_object_demarshal_generic, &priv->state },
|
||||
{ NM_ACTIVE_CONNECTION_DEFAULT, _nm_object_demarshal_generic, &priv->is_default },
|
||||
{ NM_ACTIVE_CONNECTION_DEFAULT6, _nm_object_demarshal_generic, &priv->is_default6 },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
|
@ -512,13 +545,26 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
|
|||
/**
|
||||
* NMActiveConnection:default:
|
||||
*
|
||||
* Whether the active connection is the default one.
|
||||
* Whether the active connection is the default IPv4 one.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
/**
|
||||
* NMActiveConnection:default6:
|
||||
*
|
||||
* Whether the active connection is the default IPv6 one.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ G_BEGIN_DECLS
|
|||
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
|
||||
#define NM_ACTIVE_CONNECTION_STATE "state"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6"
|
||||
|
||||
typedef struct {
|
||||
NMObject parent;
|
||||
|
|
@ -73,6 +74,7 @@ const char * nm_active_connection_get_specific_object (NMActiveConnection *c
|
|||
const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection);
|
||||
NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *connection);
|
||||
gboolean nm_active_connection_get_default (NMActiveConnection *connection);
|
||||
gboolean nm_active_connection_get_default6 (NMActiveConnection *connection);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \
|
|||
libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS)
|
||||
|
||||
libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \
|
||||
-version-info "4:2:3"
|
||||
-version-info "4:4:3"
|
||||
|
||||
if WITH_GNUTLS
|
||||
libnm_util_la_SOURCES += crypto_gnutls.c
|
||||
|
|
|
|||
|
|
@ -168,8 +168,7 @@ global:
|
|||
nm_setting_ip4_config_get_dhcp_hostname;
|
||||
nm_setting_ip4_config_get_dhcp_send_hostname;
|
||||
nm_setting_ip4_config_get_never_default;
|
||||
nm_setting_ip6_config_error_get_type;
|
||||
nm_setting_ip6_config_error_quark;
|
||||
nm_setting_ip4_config_get_may_fail;
|
||||
nm_ip6_address_new;
|
||||
nm_ip6_address_dup;
|
||||
nm_ip6_address_ref;
|
||||
|
|
@ -177,6 +176,8 @@ global:
|
|||
nm_ip6_address_compare;
|
||||
nm_ip6_address_get_address;
|
||||
nm_ip6_address_set_address;
|
||||
nm_ip6_address_get_gateway;
|
||||
nm_ip6_address_set_gateway;
|
||||
nm_ip6_address_get_prefix;
|
||||
nm_ip6_address_set_prefix;
|
||||
nm_ip6_route_new;
|
||||
|
|
@ -192,6 +193,8 @@ global:
|
|||
nm_ip6_route_set_next_hop;
|
||||
nm_ip6_route_get_metric;
|
||||
nm_ip6_route_set_metric;
|
||||
nm_setting_ip6_config_error_get_type;
|
||||
nm_setting_ip6_config_error_quark;
|
||||
nm_setting_ip6_config_get_type;
|
||||
nm_setting_ip6_config_new;
|
||||
nm_setting_ip6_config_get_method;
|
||||
|
|
@ -218,6 +221,7 @@ global:
|
|||
nm_setting_ip6_config_get_ignore_auto_routes;
|
||||
nm_setting_ip6_config_get_ignore_auto_dns;
|
||||
nm_setting_ip6_config_get_never_default;
|
||||
nm_setting_ip6_config_get_may_fail;
|
||||
nm_setting_need_secrets;
|
||||
nm_setting_ppp_error_get_type;
|
||||
nm_setting_ppp_error_quark;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -377,6 +377,7 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
GValue *tmp_val;
|
||||
GByteArray *addr1, *addr2;
|
||||
guint32 prefix1, prefix2;
|
||||
GByteArray *gw1, *gw2;
|
||||
gint ret = 0;
|
||||
int i;
|
||||
|
||||
|
|
@ -387,8 +388,8 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* Since they are NM IPv6 address structures, we expect both
|
||||
* to contain two elements as specified in nm-dbus-glib-types.h.
|
||||
*/
|
||||
g_return_val_if_fail (values1->n_values == 2, 0);
|
||||
g_return_val_if_fail (values2->n_values == 2, 0);
|
||||
g_return_val_if_fail (values1->n_values == 3, 0);
|
||||
g_return_val_if_fail (values2->n_values == 3, 0);
|
||||
|
||||
/* First struct IPv6 address */
|
||||
tmp_val = g_value_array_get_nth (values1, 0);
|
||||
|
|
@ -396,6 +397,9 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* First struct IPv6 prefix */
|
||||
tmp_val = g_value_array_get_nth (values1, 1);
|
||||
prefix1 = g_value_get_uint (tmp_val);
|
||||
/* First struct IPv6 gateway */
|
||||
tmp_val = g_value_array_get_nth (values1, 2);
|
||||
gw1 = g_value_get_boxed (tmp_val);
|
||||
|
||||
/* Second struct IPv6 address */
|
||||
tmp_val = g_value_array_get_nth (values2, 0);
|
||||
|
|
@ -403,6 +407,9 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* Second struct IPv6 prefix */
|
||||
tmp_val = g_value_array_get_nth (values2, 1);
|
||||
prefix2 = g_value_get_uint (tmp_val);
|
||||
/* Second struct IPv6 gateway */
|
||||
tmp_val = g_value_array_get_nth (values2, 2);
|
||||
gw2 = g_value_get_boxed (tmp_val);
|
||||
|
||||
/* Compare IPv6 addresses */
|
||||
if (prefix1 != prefix2)
|
||||
|
|
@ -413,6 +420,11 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
ret = addr1->data[i] < addr2->data[i] ? -1 : addr1->data[i] > addr2->data[i];
|
||||
}
|
||||
|
||||
if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *) gw1->data, (struct in6_addr *) gw2->data)) {
|
||||
for (i = 0; ret == 0 && i < gw1->len; i++)
|
||||
ret = gw1->data[i] < gw2->data[i] ? -1 : gw1->data[i] > gw2->data[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -83,6 +83,7 @@ typedef struct {
|
|||
gboolean dhcp_send_hostname;
|
||||
char *dhcp_hostname;
|
||||
gboolean never_default;
|
||||
gboolean may_fail;
|
||||
} NMSettingIP4ConfigPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -98,6 +99,7 @@ enum {
|
|||
PROP_DHCP_SEND_HOSTNAME,
|
||||
PROP_DHCP_HOSTNAME,
|
||||
PROP_NEVER_DEFAULT,
|
||||
PROP_MAY_FAIL,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -438,6 +440,14 @@ nm_setting_ip4_config_get_never_default (NMSettingIP4Config *setting)
|
|||
return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->never_default;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_ip4_config_get_may_fail (NMSettingIP4Config *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE);
|
||||
|
||||
return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->may_fail;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, GSList *all_settings, GError **error)
|
||||
{
|
||||
|
|
@ -462,7 +472,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
} else if ( !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
if (priv->dns && priv->dns->len) {
|
||||
g_set_error (error,
|
||||
NM_SETTING_IP4_CONFIG_ERROR,
|
||||
|
|
@ -640,6 +651,9 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_NEVER_DEFAULT:
|
||||
priv->never_default = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MAY_FAIL:
|
||||
priv->may_fail = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -687,6 +701,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_NEVER_DEFAULT:
|
||||
g_value_set_boolean (value, priv->never_default);
|
||||
break;
|
||||
case PROP_MAY_FAIL:
|
||||
g_value_set_boolean (value, priv->may_fail);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -721,7 +738,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* network access to other computers) then the interface is assigned an
|
||||
* address in the 10.42.x.1/24 range and a DHCP and forwarding DNS server
|
||||
* are started, and the interface is NAT-ed to the current default network
|
||||
* connection. This property must be set.
|
||||
* connection. 'disabled' means IPv4 will not be used on this connection.
|
||||
* This property must be set.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_METHOD,
|
||||
|
|
@ -742,7 +760,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"address in the 10.42.x.1/24 range and a DHCP and "
|
||||
"forwarding DNS server are started, and the "
|
||||
"interface is NAT-ed to the current default network "
|
||||
"connection. This property must be set.",
|
||||
"connection. 'disabled' means IPv4 will not be "
|
||||
"used on this connection. This property must be set.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -751,8 +770,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
*
|
||||
* List of DNS servers (network byte order). For the 'auto' method, these
|
||||
* DNS servers are appended to those (if any) returned by automatic
|
||||
* configuration. DNS servers cannot be used with the 'shared' or
|
||||
* 'link-local' methods as there is no usptream network. In all other
|
||||
* configuration. DNS servers cannot be used with the 'shared', 'link-local',
|
||||
* or 'disabled' methods as there is no usptream network. In all other
|
||||
* methods, these DNS servers are used as the only DNS servers for this
|
||||
* connection.
|
||||
**/
|
||||
|
|
@ -764,10 +783,10 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"the 'auto' method, these DNS servers are "
|
||||
"appended to those (if any) returned by automatic "
|
||||
"configuration. DNS servers cannot be used with "
|
||||
"the 'shared' or 'link-local' methods as there is "
|
||||
"no usptream network. In all other methods, "
|
||||
"these DNS servers are used as the only DNS "
|
||||
"servers for this connection.",
|
||||
"the 'shared', 'link-local', or 'disabled' "
|
||||
"methods as there is no usptream network. In all "
|
||||
"other methods, these DNS servers are used as the "
|
||||
"only DNS servers for this connection.",
|
||||
DBUS_TYPE_G_UINT_ARRAY,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -776,9 +795,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
*
|
||||
* List of DNS search domains. For the 'auto' method, these search domains
|
||||
* are appended to those returned by automatic configuration. Search domains
|
||||
* cannot be used with the 'shared' or 'link-local' methods as there is no
|
||||
* upstream network. In all other methods, these search domains are used
|
||||
* as the only search domains for this connection.
|
||||
* cannot be used with the 'shared', 'link-local', or 'disabled' methods as
|
||||
* there is no upstream network. In all other methods, these search domains
|
||||
* are used as the only search domains for this connection.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DNS_SEARCH,
|
||||
|
|
@ -787,11 +806,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"List of DNS search domains. For the 'auto' "
|
||||
"method, these search domains are appended to "
|
||||
"those returned by automatic configuration. "
|
||||
"Search domains cannot be used with the 'shared' "
|
||||
"or 'link-local' methods as there is no upstream "
|
||||
"network. In all other methods, these search "
|
||||
"domains are used as the only search domains for "
|
||||
"this connection.",
|
||||
"Search domains cannot be used with the 'shared', "
|
||||
"'link-local', or 'disabled' methods as there is "
|
||||
"no upstream network. In all other methods, these "
|
||||
"search domains are used as the only search domains "
|
||||
"for this connection.",
|
||||
DBUS_TYPE_G_LIST_OF_STRING,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -804,8 +823,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* (network byte order). The gateway may be left as 0 if no gateway exists
|
||||
* for that subnet. For the 'auto' method, given IP addresses are appended
|
||||
* to those returned by automatic configuration. Addresses cannot be used
|
||||
* with the 'shared' or 'link-local' methods as the interface is
|
||||
* automatically assigned an address with these methods.
|
||||
* with the 'shared', 'link-local', or 'disabled' methods as addressing is
|
||||
* either automatic or disabled with these methods.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
|
|
@ -820,9 +839,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"for that subnet. For the 'auto' method, given "
|
||||
"IP addresses are appended to those returned by "
|
||||
"automatic configuration. Addresses cannot be "
|
||||
"used with the 'shared' or 'link-local' methods "
|
||||
"as the interface is automatically assigned an "
|
||||
"address with these methods.",
|
||||
"used with the 'shared', 'link-local', or "
|
||||
"'disabled' methods as addressing is either "
|
||||
"automatic or disabled with these methods.",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -835,8 +854,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* address prefix (1 - 32), the third being the next-hop (network byte
|
||||
* order) if any, and the fourth being the route metric. For the 'auto'
|
||||
* method, given IP routes are appended to those returned by automatic
|
||||
* configuration. Routes cannot be used with the 'shared' or 'link-local'
|
||||
* methods because there is no upstream network.
|
||||
* configuration. Routes cannot be used with the 'shared', 'link-local',
|
||||
* or 'disabled' methods because there is no upstream network.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ROUTES,
|
||||
|
|
@ -852,8 +871,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"For the 'auto' method, given IP routes are "
|
||||
"appended to those returned by automatic "
|
||||
"configuration. Routes cannot be used with the "
|
||||
"'shared' or 'link-local' methods as there is no "
|
||||
"upstream network.",
|
||||
"'shared', 'link-local', or 'disabled', methods "
|
||||
"as there is no upstream network.",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -965,6 +984,31 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"the default route by NetworkManager.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
/**
|
||||
* NMSettingIP4Config:may-fail:
|
||||
*
|
||||
* If TRUE, allow overall network configuration to proceed even if IPv4
|
||||
* configuration times out. Note that at least one IP configuration
|
||||
* must succeed or overall network configuration will still fail. For
|
||||
* example, in IPv6-only networks, setting this property to TRUE allows
|
||||
* the overall network configuration to succeed if IPv4 configuration fails
|
||||
* but IPv6 configuration completes successfully.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_MAY_FAIL,
|
||||
g_param_spec_boolean (NM_SETTING_IP4_CONFIG_MAY_FAIL,
|
||||
"May Fail",
|
||||
"If TRUE, allow overall network configuration to "
|
||||
"proceed even if IPv4 configuration times out. "
|
||||
"Note that at least one IP configuration must "
|
||||
"succeed or overall network configuration will still "
|
||||
"fail. For example, in IPv6-only networks, setting "
|
||||
"this property to TRUE allows the overall network "
|
||||
"configuration to succeed if IPv4 configuration "
|
||||
"fails but IPv6 configuration completes successfully.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -64,11 +64,13 @@ GQuark nm_setting_ip4_config_error_quark (void);
|
|||
#define NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME "dhcp-send-hostname"
|
||||
#define NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME "dhcp-hostname"
|
||||
#define NM_SETTING_IP4_CONFIG_NEVER_DEFAULT "never-default"
|
||||
#define NM_SETTING_IP4_CONFIG_MAY_FAIL "may-fail"
|
||||
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_AUTO "auto"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_MANUAL "manual"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_SHARED "shared"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_DISABLED "disabled"
|
||||
|
||||
typedef struct NMIP4Address NMIP4Address;
|
||||
|
||||
|
|
@ -168,6 +170,8 @@ const char * nm_setting_ip4_config_get_dhcp_hostname (NMSettingIP4Config *
|
|||
|
||||
gboolean nm_setting_ip4_config_get_never_default (NMSettingIP4Config *setting);
|
||||
|
||||
gboolean nm_setting_ip4_config_get_may_fail (NMSettingIP4Config *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_SETTING_IP4_CONFIG_H */
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ typedef struct {
|
|||
gboolean ignore_auto_routes;
|
||||
gboolean ignore_auto_dns;
|
||||
gboolean never_default;
|
||||
gboolean may_fail;
|
||||
} NMSettingIP6ConfigPrivate;
|
||||
|
||||
|
||||
|
|
@ -92,6 +93,7 @@ enum {
|
|||
PROP_IGNORE_AUTO_ROUTES,
|
||||
PROP_IGNORE_AUTO_DNS,
|
||||
PROP_NEVER_DEFAULT,
|
||||
PROP_MAY_FAIL,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -414,6 +416,14 @@ nm_setting_ip6_config_get_never_default (NMSettingIP6Config *setting)
|
|||
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->never_default;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_setting_ip6_config_get_may_fail (NMSettingIP6Config *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), FALSE);
|
||||
|
||||
return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->may_fail;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, GSList *all_settings, GError **error)
|
||||
{
|
||||
|
|
@ -535,6 +545,9 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_NEVER_DEFAULT:
|
||||
priv->never_default = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MAY_FAIL:
|
||||
priv->may_fail = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -572,6 +585,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_NEVER_DEFAULT:
|
||||
g_value_set_boolean (value, priv->never_default);
|
||||
break;
|
||||
case PROP_MAY_FAIL:
|
||||
g_value_set_boolean (value, priv->may_fail);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -684,25 +700,32 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
|
|||
* NMSettingIP6Config:addresses:
|
||||
*
|
||||
* Array of IPv6 address structures. Each IPv6 address structure is
|
||||
* composed of 2 members, the first being a byte array containing the IPv6
|
||||
* address (network byte order) and the second a 32-bit integer containing
|
||||
* the IPv6 address prefix. For the 'auto' method, given IP addresses are
|
||||
* appended to those returned by automatic configuration. Addresses cannot
|
||||
* be used with the 'shared' or 'link-local' methods as the interface is
|
||||
* automatically assigned an address with these methods.
|
||||
* composed of 3 members, the first being a byte array containing the IPv6
|
||||
* address (network byte order), the second a 32-bit integer containing the
|
||||
* IPv6 address prefix, and the third a byte array containing the IPv6
|
||||
* address (network byte order) of the gateway associated with this address,
|
||||
* if any. If no gateway is given, the third element should be given as
|
||||
* all zeros. For the 'auto' method, given IP addresses are appended to
|
||||
* those returned by automatic configuration. Addresses cannot be used with
|
||||
* the 'shared' or 'link-local' methods as the interface is automatically
|
||||
* assigned an address with these methods.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
_nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"Array of IPv6 address structures. Each IPv6 "
|
||||
"address structure is composed of 2 members, the "
|
||||
"address structure is composed of 3 members, the "
|
||||
"first being a byte array containing the IPv6 "
|
||||
"address (network byte order) and the second a "
|
||||
"address (network byte order), the second a "
|
||||
"32-bit integer containing the IPv6 address "
|
||||
"prefix. For the 'auto' method, given IP "
|
||||
"addresses are appended to those returned by "
|
||||
"automatic configuration. Addresses cannot be "
|
||||
"prefix, and the third a byte array containing "
|
||||
"the IPv6 address (network byte order) of the "
|
||||
"gateway associated with this address, if any. "
|
||||
"If no gateway is given, the third element should "
|
||||
"be given as all zeros. For the 'auto' method, "
|
||||
"given IP addresses are appended to those returned "
|
||||
"by automatic configuration. Addresses cannot be "
|
||||
"used with the 'shared' or 'link-local' methods "
|
||||
"as the interface is automatically assigned an "
|
||||
"address with these methods.",
|
||||
|
|
@ -795,12 +818,39 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
|
|||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
/**
|
||||
* NMSettingIP6Config:may-fail:
|
||||
*
|
||||
* If TRUE, allow overall network configuration to proceed even if IPv6
|
||||
* configuration times out. Note that at least one IP configuration
|
||||
* must succeed or overall network configuration will still fail. For
|
||||
* example, in IPv4-only networks, setting this property to TRUE allows
|
||||
* the overall network configuration to succeed if IPv6 configuration fails
|
||||
* but IPv4 configuration completes successfully.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_MAY_FAIL,
|
||||
g_param_spec_boolean (NM_SETTING_IP6_CONFIG_MAY_FAIL,
|
||||
"May Fail",
|
||||
"If TRUE, allow overall network configuration to "
|
||||
"proceed even if IPv6 configuration times out. "
|
||||
"Note that at least one IP configuration must "
|
||||
"succeed or overall network configuration will still "
|
||||
"fail. For example, in IPv4-only networks, setting "
|
||||
"this property to TRUE allows the overall network "
|
||||
"configuration to succeed if IPv6 configuration "
|
||||
"fails but IPv4 configuration completes successfully.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
struct NMIP6Address {
|
||||
guint32 refcount;
|
||||
struct in6_addr address;
|
||||
guint32 prefix;
|
||||
struct in6_addr gateway;
|
||||
};
|
||||
|
||||
NMIP6Address *
|
||||
|
|
@ -824,6 +874,7 @@ nm_ip6_address_dup (NMIP6Address *source)
|
|||
address = nm_ip6_address_new ();
|
||||
address->prefix = source->prefix;
|
||||
memcpy (&address->address, &source->address, sizeof (struct in6_addr));
|
||||
memcpy (&address->gateway, &source->gateway, sizeof (struct in6_addr));
|
||||
|
||||
return address;
|
||||
}
|
||||
|
|
@ -860,7 +911,8 @@ nm_ip6_address_compare (NMIP6Address *address, NMIP6Address *other)
|
|||
g_return_val_if_fail (other->refcount > 0, FALSE);
|
||||
|
||||
if ( memcmp (&address->address, &other->address, sizeof (struct in6_addr))
|
||||
|| address->prefix != other->prefix)
|
||||
|| address->prefix != other->prefix
|
||||
|| memcmp (&address->gateway, &other->gateway, sizeof (struct in6_addr)))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -902,6 +954,27 @@ nm_ip6_address_set_prefix (NMIP6Address *address, guint32 prefix)
|
|||
address->prefix = prefix;
|
||||
}
|
||||
|
||||
const struct in6_addr *
|
||||
nm_ip6_address_get_gateway (NMIP6Address *address)
|
||||
{
|
||||
g_return_val_if_fail (address != NULL, 0);
|
||||
g_return_val_if_fail (address->refcount > 0, 0);
|
||||
|
||||
return &address->gateway;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_address_set_gateway (NMIP6Address *address, const struct in6_addr *gw)
|
||||
{
|
||||
g_return_if_fail (address != NULL);
|
||||
g_return_if_fail (address->refcount > 0);
|
||||
g_return_if_fail (gw != NULL);
|
||||
|
||||
memcpy (&address->gateway, gw, sizeof (struct in6_addr));
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
struct NMIP6Route {
|
||||
guint32 refcount;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ GQuark nm_setting_ip6_config_error_quark (void);
|
|||
#define NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes"
|
||||
#define NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns"
|
||||
#define NM_SETTING_IP6_CONFIG_NEVER_DEFAULT "never-default"
|
||||
#define NM_SETTING_IP6_CONFIG_MAY_FAIL "may-fail"
|
||||
|
||||
#define NM_SETTING_IP6_CONFIG_METHOD_IGNORE "ignore"
|
||||
#define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto"
|
||||
|
|
@ -88,6 +89,10 @@ guint32 nm_ip6_address_get_prefix (NMIP6Address *address);
|
|||
void nm_ip6_address_set_prefix (NMIP6Address *address,
|
||||
guint32 prefix);
|
||||
|
||||
const struct in6_addr *nm_ip6_address_get_gateway (NMIP6Address *address);
|
||||
void nm_ip6_address_set_gateway (NMIP6Address *address,
|
||||
const struct in6_addr *gw);
|
||||
|
||||
typedef struct NMIP6Route NMIP6Route;
|
||||
|
||||
NMIP6Route * nm_ip6_route_new (void);
|
||||
|
|
@ -159,6 +164,7 @@ gboolean nm_setting_ip6_config_get_ignore_auto_routes (NMSettingIP
|
|||
|
||||
gboolean nm_setting_ip6_config_get_ignore_auto_dns (NMSettingIP6Config *setting);
|
||||
gboolean nm_setting_ip6_config_get_never_default (NMSettingIP6Config *setting);
|
||||
gboolean nm_setting_ip6_config_get_may_fail (NMSettingIP6Config *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,8 @@ nm_utils_init (GError **error)
|
|||
if (!crypto_init (error))
|
||||
return FALSE;
|
||||
|
||||
_nm_utils_register_value_transformations ();
|
||||
|
||||
atexit (nm_utils_deinit);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
|
@ -745,7 +747,8 @@ nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_va
|
|||
hash = (GHashTable *) g_value_get_boxed (src_value);
|
||||
|
||||
printable = g_string_new ("[");
|
||||
g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
|
||||
if (hash)
|
||||
g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
|
||||
g_string_append (printable, " ]");
|
||||
|
||||
g_value_take_string (dest_value, printable->str);
|
||||
|
|
@ -858,10 +861,11 @@ nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValu
|
|||
|
||||
g_string_append (printable, "{ ");
|
||||
elements = (GValueArray *) g_ptr_array_index (ptr_array, i++);
|
||||
if ( (elements->n_values != 2)
|
||||
if ( (elements->n_values != 3)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) {
|
||||
g_string_append (printable, "invalid");
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) {
|
||||
g_string_append (printable, "invalid }");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -869,7 +873,7 @@ nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValu
|
|||
tmp = g_value_array_get_nth (elements, 0);
|
||||
ba_addr = g_value_get_boxed (tmp);
|
||||
if (ba_addr->len != 16) {
|
||||
g_string_append (printable, "invalid");
|
||||
g_string_append (printable, "invalid }");
|
||||
continue;
|
||||
}
|
||||
addr = (struct in6_addr *) ba_addr->data;
|
||||
|
|
@ -882,10 +886,23 @@ nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValu
|
|||
tmp = g_value_array_get_nth (elements, 1);
|
||||
prefix = g_value_get_uint (tmp);
|
||||
if (prefix > 128) {
|
||||
g_string_append (printable, "invalid");
|
||||
g_string_append (printable, "invalid }");
|
||||
continue;
|
||||
}
|
||||
g_string_append_printf (printable, "px = %u", prefix);
|
||||
g_string_append (printable, ", ");
|
||||
|
||||
/* IPv6 Gateway */
|
||||
tmp = g_value_array_get_nth (elements, 2);
|
||||
ba_addr = g_value_get_boxed (tmp);
|
||||
if (ba_addr->len != 16) {
|
||||
g_string_append (printable, "invalid }");
|
||||
continue;
|
||||
}
|
||||
addr = (struct in6_addr *) ba_addr->data;
|
||||
memset (buf, 0, sizeof (buf));
|
||||
nm_utils_inet6_ntop (addr, buf);
|
||||
g_string_append_printf (printable, "gw = %s", buf);
|
||||
g_string_append (printable, " }");
|
||||
}
|
||||
g_string_append_c (printable, ']');
|
||||
|
|
@ -977,6 +994,58 @@ nm_utils_convert_ip6_route_struct_array_to_string (const GValue *src_value, GVal
|
|||
g_string_free (printable, FALSE);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
static void
|
||||
nm_utils_convert_old_ip6_addr_array (const GValue *src_value, GValue *dst_value)
|
||||
{
|
||||
GPtrArray *src_outer_array;
|
||||
GPtrArray *dst_outer_array;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS));
|
||||
|
||||
src_outer_array = (GPtrArray *) g_value_get_boxed (src_value);
|
||||
dst_outer_array = g_ptr_array_new ();
|
||||
|
||||
for (i = 0; src_outer_array && (i < src_outer_array->len); i++) {
|
||||
GValueArray *src_addr_array;
|
||||
GValueArray *dst_addr_array;
|
||||
GValue element = {0, };
|
||||
GValue *src_addr, *src_prefix;
|
||||
GByteArray *ba;
|
||||
|
||||
src_addr_array = (GValueArray *) g_ptr_array_index (src_outer_array, i);
|
||||
|
||||
if ( (src_addr_array->n_values != 2)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (src_addr_array, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (src_addr_array, 1)) != G_TYPE_UINT)) {
|
||||
g_warning ("%s: invalid old IPv6 address type", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dst_addr_array = g_value_array_new (3);
|
||||
|
||||
src_addr = g_value_array_get_nth (src_addr_array, 0);
|
||||
g_value_array_append (dst_addr_array, src_addr);
|
||||
src_prefix = g_value_array_get_nth (src_addr_array, 1);
|
||||
g_value_array_append (dst_addr_array, src_prefix);
|
||||
|
||||
/* Blank Gateway */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (dst_addr_array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (dst_outer_array, dst_addr_array);
|
||||
}
|
||||
|
||||
g_value_take_boxed (dst_value, dst_outer_array);
|
||||
}
|
||||
|
||||
void
|
||||
_nm_utils_register_value_transformations (void)
|
||||
{
|
||||
|
|
@ -1013,6 +1082,9 @@ _nm_utils_register_value_transformations (void)
|
|||
g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
|
||||
G_TYPE_STRING,
|
||||
nm_utils_convert_ip6_route_struct_array_to_string);
|
||||
g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
nm_utils_convert_old_ip6_addr_array);
|
||||
registered = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1459,8 +1531,8 @@ nm_utils_ip4_get_default_prefix (guint32 ip)
|
|||
* @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and guint32
|
||||
*
|
||||
* Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and guint32
|
||||
* representing a list of NetworkManager IPv6 addresses (which is a pair of address
|
||||
* and prefix), into a GSList of #NMIP6Address objects. The specific format of
|
||||
* representing a list of NetworkManager IPv6 addresses (which is a tuple of address,
|
||||
* prefix, and gateway), into a GSList of #NMIP6Address objects. The specific format of
|
||||
* this serialization is not guaranteed to be stable and the #GValueArray may be
|
||||
* extended in the future.
|
||||
*
|
||||
|
|
@ -1479,16 +1551,28 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
GValueArray *elements = (GValueArray *) g_ptr_array_index (addresses, i);
|
||||
GValue *tmp;
|
||||
GByteArray *ba_addr;
|
||||
GByteArray *ba_gw = NULL;
|
||||
NMIP6Address *addr;
|
||||
guint32 prefix;
|
||||
|
||||
if ( (elements->n_values != 2)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
if (elements->n_values < 2 || elements->n_values > 3) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check optional 3rd element (gateway) */
|
||||
if ( elements->n_values == 3
|
||||
&& (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = g_value_array_get_nth (elements, 0);
|
||||
ba_addr = g_value_get_boxed (tmp);
|
||||
if (ba_addr->len != 16) {
|
||||
|
|
@ -1505,9 +1589,22 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (elements->n_values == 3) {
|
||||
tmp = g_value_array_get_nth (elements, 2);
|
||||
ba_gw = g_value_get_boxed (tmp);
|
||||
if (ba_gw->len != 16) {
|
||||
nm_warning ("%s: ignoring invalid IP6 gateway address of length %d",
|
||||
__func__, ba_gw->len);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
addr = nm_ip6_address_new ();
|
||||
nm_ip6_address_set_prefix (addr, prefix);
|
||||
nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data);
|
||||
if (ba_gw)
|
||||
nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data);
|
||||
|
||||
list = g_slist_prepend (list, addr);
|
||||
}
|
||||
|
||||
|
|
@ -1522,10 +1619,10 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
* g_value_unset().
|
||||
*
|
||||
* Utility function to convert a #GSList of #NMIP6Address objects into a
|
||||
* GPtrArray of GValueArrays of (GArray or guchars) and guint32 representing a list
|
||||
* of NetworkManager IPv6 addresses (which is a pair of address and prefix).
|
||||
* The specific format of this serialization is not guaranteed to be stable and may be
|
||||
* extended in the future.
|
||||
* GPtrArray of GValueArrays representing a list of NetworkManager IPv6 addresses
|
||||
* (which is a tuple of address, prefix, and gateway). The specific format of
|
||||
* this serialization is not guaranteed to be stable and may be extended in the
|
||||
* future.
|
||||
**/
|
||||
void
|
||||
nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
||||
|
|
@ -1541,8 +1638,9 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
|||
GValue element = {0, };
|
||||
GByteArray *ba;
|
||||
|
||||
array = g_value_array_new (2);
|
||||
array = g_value_array_new (3);
|
||||
|
||||
/* IP address */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16);
|
||||
|
|
@ -1550,11 +1648,20 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
|||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Prefix */
|
||||
g_value_init (&element, G_TYPE_UINT);
|
||||
g_value_set_uint (&element, nm_ip6_address_get_prefix (addr));
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Gateway */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16);
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (addresses, array);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2008 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
|
||||
static void
|
||||
vpn_check_func (const char *key, const char *value, gpointer user_data)
|
||||
|
|
@ -128,6 +129,99 @@ test_setting_vpn_items (void)
|
|||
g_object_unref (s_vpn);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
/* Test that setting the IPv6 setting's 'addresses' property using the old
|
||||
* IPv6 address format still works, i.e. that the GValue transformation function
|
||||
* from old->new is working correctly.
|
||||
*/
|
||||
static void
|
||||
test_setting_ip6_config_old_address_array (void)
|
||||
{
|
||||
NMSettingIP6Config *s_ip6;
|
||||
GPtrArray *addresses, *read_addresses;
|
||||
GValueArray *array, *read_array;
|
||||
GValue element = {0, }, written_value = {0, }, read_value = {0, };
|
||||
GByteArray *ba;
|
||||
const guint8 addr[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
|
||||
0x11, 0x22, 0x33, 0x44, 0x66, 0x77, 0x88, 0x99 };
|
||||
const guint8 gw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
guint32 prefix = 56;
|
||||
GValue *read_addr, *read_prefix, *read_gw;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
ASSERT (s_ip6 != NULL,
|
||||
"ip6-old-addr", "error creating IP6 setting");
|
||||
|
||||
g_value_init (&written_value, OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
|
||||
|
||||
addresses = g_ptr_array_new ();
|
||||
array = g_value_array_new (3);
|
||||
|
||||
/* IP address */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, &addr[0], sizeof (addr));
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Prefix */
|
||||
g_value_init (&element, G_TYPE_UINT);
|
||||
g_value_set_uint (&element, prefix);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (addresses, array);
|
||||
g_value_set_boxed (&written_value, addresses);
|
||||
|
||||
/* Set the address array on the object */
|
||||
g_object_set_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &written_value);
|
||||
|
||||
/* Get it back so we can compare it */
|
||||
g_value_init (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
|
||||
g_object_get_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &read_value);
|
||||
|
||||
ASSERT (G_VALUE_HOLDS (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS),
|
||||
"ip6-old-addr", "wrong addresses property value type '%s'",
|
||||
G_VALUE_TYPE_NAME (&read_value));
|
||||
|
||||
read_addresses = (GPtrArray *) g_value_get_boxed (&read_value);
|
||||
ASSERT (read_addresses != NULL,
|
||||
"ip6-old-addr", "missing addresses on readback");
|
||||
ASSERT (read_addresses->len == 1,
|
||||
"ip6-old-addr", "expected one address on readback");
|
||||
|
||||
read_array = (GValueArray *) g_ptr_array_index (read_addresses, 0);
|
||||
|
||||
read_addr = g_value_array_get_nth (read_array, 0);
|
||||
ba = g_value_get_boxed (read_addr);
|
||||
ASSERT (ba->len == sizeof (addr),
|
||||
"ip6-old-addr", "unexpected address item length %d", ba->len);
|
||||
ASSERT (memcmp (ba->data, &addr[0], sizeof (addr)) == 0,
|
||||
"ip6-old-addr", "unexpected failure comparing addresses");
|
||||
|
||||
read_prefix = g_value_array_get_nth (read_array, 1);
|
||||
ASSERT (g_value_get_uint (read_prefix) == prefix,
|
||||
"ip6-old-addr", "unexpected failure comparing prefix");
|
||||
|
||||
/* Ensure the gateway is all zeros, which is how the 2-item to 3-item
|
||||
* conversion happens.
|
||||
*/
|
||||
read_gw = g_value_array_get_nth (read_array, 2);
|
||||
ba = g_value_get_boxed (read_gw);
|
||||
ASSERT (ba->len == sizeof (gw),
|
||||
"ip6-old-addr", "unexpected gateway item length %d", ba->len);
|
||||
ASSERT (memcmp (ba->data, &gw[0], sizeof (gw)) == 0,
|
||||
"ip6-old-addr", "unexpected failure comparing gateways");
|
||||
|
||||
g_value_unset (&written_value);
|
||||
g_value_unset (&read_value);
|
||||
g_object_unref (s_ip6);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
|
@ -142,6 +236,7 @@ int main (int argc, char **argv)
|
|||
|
||||
/* The tests */
|
||||
test_setting_vpn_items ();
|
||||
test_setting_ip6_config_old_address_array ();
|
||||
|
||||
base = g_path_get_basename (argv[0]);
|
||||
fprintf (stdout, "%s: SUCCESS\n", base);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ VOID:POINTER,POINTER
|
|||
VOID:STRING,STRING,STRING,UINT
|
||||
VOID:OBJECT,UINT,UINT
|
||||
VOID:STRING,INT
|
||||
VOID:STRING,UINT
|
||||
VOID:STRING,UINT,BOOLEAN
|
||||
VOID:INT,UINT
|
||||
VOID:INT,UINT,BOOLEAN
|
||||
VOID:OBJECT,OBJECT,ENUM
|
||||
VOID:POINTER,STRING
|
||||
VOID:STRING,BOXED
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ src/nm-netlink-monitor.c
|
|||
src/main.c
|
||||
src/dhcp-manager/nm-dhcp-dhclient.c
|
||||
src/dhcp-manager/nm-dhcp-manager.c
|
||||
src/ip6-manager/nm-netlink-listener.c
|
||||
src/logging/nm-logging.c
|
||||
src/named-manager/nm-named-manager.c
|
||||
src/system-settings/nm-default-wired-connection.c
|
||||
|
|
|
|||
|
|
@ -68,9 +68,11 @@ libtest_policy_hosts_la_SOURCES = \
|
|||
nm-policy-hosts.h
|
||||
|
||||
libtest_policy_hosts_la_CPPFLAGS = \
|
||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||
$(GLIB_CFLAGS)
|
||||
|
||||
libtest_policy_hosts_la_LIBADD = \
|
||||
${top_builddir}/src/logging/libnm-logging.la \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
||||
|
|
@ -123,6 +125,8 @@ NetworkManager_SOURCES = \
|
|||
nm-policy.h \
|
||||
nm-policy-hosts.c \
|
||||
nm-policy-hosts.h \
|
||||
nm-policy-hostname.c \
|
||||
nm-policy-hostname.h \
|
||||
NetworkManagerUtils.c \
|
||||
NetworkManagerUtils.h \
|
||||
nm-system.c \
|
||||
|
|
@ -137,8 +141,6 @@ NetworkManager_SOURCES = \
|
|||
nm-properties-changed-signal.h \
|
||||
wpa.c \
|
||||
wpa.h \
|
||||
nm-netlink.c \
|
||||
nm-netlink.h \
|
||||
nm-dhcp4-config.c \
|
||||
nm-dhcp4-config.h \
|
||||
nm-dhcp6-config.c \
|
||||
|
|
@ -206,9 +208,7 @@ BUILT_SOURCES = \
|
|||
NetworkManager_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(HAL_CFLAGS) \
|
||||
$(GUDEV_CFLAGS) \
|
||||
$(OPENSSL_CFLAGS) \
|
||||
$(LIBNL_CFLAGS) \
|
||||
$(GMODULE_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@
|
|||
|
||||
<allow send_destination="org.freedesktop.NetworkManager"
|
||||
send_interface="org.freedesktop.NetworkManager.VPN.Connection"/>
|
||||
|
||||
<deny send_destination="org.freedesktop.NetworkManager"
|
||||
send_interface="org.freedesktop.NetworkManager"
|
||||
send_member="SetLogging"/>
|
||||
</policy>
|
||||
<policy context="default">
|
||||
<deny own="org.freedesktop.NetworkManager"/>
|
||||
|
|
@ -64,6 +68,10 @@
|
|||
<deny send_destination="org.freedesktop.NetworkManager"/>
|
||||
<allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
|
||||
|
||||
<deny send_destination="org.freedesktop.NetworkManager"
|
||||
send_interface="org.freedesktop.NetworkManager"
|
||||
send_member="SetLogging"/>
|
||||
|
||||
<!-- The org.freedesktop.NetworkManagerSettings.Connection.Secrets
|
||||
interface is secured via PolicyKit.
|
||||
-->
|
||||
|
|
|
|||
|
|
@ -594,3 +594,32 @@ nm_utils_do_sysctl (const char *path, const char *value)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_utils_get_proc_sys_net_value (const char *path,
|
||||
const char *iface,
|
||||
guint32 *out_value)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *contents = NULL;
|
||||
gboolean success = FALSE;
|
||||
long int tmp;
|
||||
|
||||
if (!g_file_get_contents (path, &contents, NULL, &error)) {
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s): error reading %s: (%d) %s",
|
||||
iface, path,
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
errno = 0;
|
||||
tmp = strtol (contents, NULL, 10);
|
||||
if ((errno == 0) && (tmp == 0 || tmp == 1)) {
|
||||
*out_value = (guint32) tmp;
|
||||
success = TRUE;
|
||||
}
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,4 +73,8 @@ void value_hash_add_bool (GHashTable *hash,
|
|||
|
||||
gboolean nm_utils_do_sysctl (const char *path, const char *value);
|
||||
|
||||
gboolean nm_utils_get_proc_sys_net_value (const char *path,
|
||||
const char *iface,
|
||||
guint32 *out_value);
|
||||
|
||||
#endif /* NETWORK_MANAGER_UTILS_H */
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Timothee Lecomte <timothee.lecomte@ens.fr>
|
||||
*
|
||||
* Heavily based on NetworkManagerRedhat.c by Dan Williams <dcbw@redhat.com>
|
||||
*
|
||||
* 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
|
||||
|
|
@ -19,7 +15,8 @@
|
|||
* 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 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2006 Timothee Lecomte <timothee.lecomte@ens.fr>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -36,8 +33,8 @@
|
|||
#include "NetworkManagerGeneric.h"
|
||||
#include "nm-system.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
|
||||
/* Because of a bug in libnl, rtnl.h should be included before route.h */
|
||||
#include <netlink/route/rtnl.h>
|
||||
|
|
|
|||
|
|
@ -41,9 +41,13 @@ typedef struct {
|
|||
|
||||
guchar state;
|
||||
GPid pid;
|
||||
gboolean dead;
|
||||
guint timeout_id;
|
||||
guint watch_id;
|
||||
guint32 remove_id;
|
||||
GHashTable * options;
|
||||
gboolean info_only;
|
||||
|
||||
} NMDHCPClientPrivate;
|
||||
|
||||
#define NM_DHCP_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_CLIENT, NMDHCPClientPrivate))
|
||||
|
|
@ -53,6 +57,7 @@ G_DEFINE_TYPE_EXTENDED (NMDHCPClient, nm_dhcp_client, G_TYPE_OBJECT, G_TYPE_FLAG
|
|||
enum {
|
||||
STATE_CHANGED,
|
||||
TIMEOUT,
|
||||
REMOVE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
|
@ -186,6 +191,8 @@ real_stop (NMDHCPClient *self)
|
|||
watch_cleanup (self);
|
||||
|
||||
stop_process (priv->pid, priv->iface);
|
||||
|
||||
priv->info_only = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -203,22 +210,68 @@ daemon_timeout (gpointer user_data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
signal_remove (gpointer user_data)
|
||||
{
|
||||
NMDHCPClient *self = NM_DHCP_CLIENT (user_data);
|
||||
|
||||
NM_DHCP_CLIENT_GET_PRIVATE (self)->remove_id = 0;
|
||||
g_signal_emit (G_OBJECT (self), signals[REMOVE], 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
dhcp_client_set_state (NMDHCPClient *self,
|
||||
NMDHCPState state,
|
||||
gboolean emit_state,
|
||||
gboolean remove_now)
|
||||
{
|
||||
NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
|
||||
priv->state = state;
|
||||
|
||||
if (emit_state)
|
||||
g_signal_emit (G_OBJECT (self), signals[STATE_CHANGED], 0, priv->state);
|
||||
|
||||
if (state == DHC_END || state == DHC_ABEND) {
|
||||
/* Start the remove signal timer */
|
||||
if (remove_now) {
|
||||
g_signal_emit (G_OBJECT (self), signals[REMOVE], 0);
|
||||
} else {
|
||||
if (!priv->remove_id)
|
||||
priv->remove_id = g_timeout_add_seconds (5, signal_remove, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
daemon_watch_cb (GPid pid, gint status, gpointer user_data)
|
||||
{
|
||||
NMDHCPClient *self = NM_DHCP_CLIENT (user_data);
|
||||
NMDHCPClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
NMDHCPState new_state;
|
||||
|
||||
if (priv->ipv6) {
|
||||
nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 client pid %d exited with status %d",
|
||||
priv->iface, pid,
|
||||
WIFEXITED (status) ? WEXITSTATUS (status) : -1);
|
||||
} else {
|
||||
nm_log_info (LOGD_DHCP6, "(%s): DHCPv4 client pid %d exited with status %d",
|
||||
priv->iface, pid,
|
||||
WIFEXITED (status) ? WEXITSTATUS (status) : -1);
|
||||
}
|
||||
|
||||
if (!WIFEXITED (status)) {
|
||||
priv->state = DHC_ABEND;
|
||||
new_state = DHC_ABEND;
|
||||
nm_log_warn (LOGD_DHCP, "DHCP client died abnormally");
|
||||
}
|
||||
priv->pid = 0;
|
||||
} else
|
||||
new_state = DHC_END;
|
||||
|
||||
watch_cleanup (self);
|
||||
timeout_cleanup (self);
|
||||
priv->dead = TRUE;
|
||||
|
||||
g_signal_emit (G_OBJECT (self), signals[STATE_CHANGED], 0, priv->state);
|
||||
dhcp_client_set_state (self, new_state, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -278,6 +331,8 @@ nm_dhcp_client_start_ip6 (NMDHCPClient *self,
|
|||
g_return_val_if_fail (priv->ipv6 == TRUE, FALSE);
|
||||
g_return_val_if_fail (priv->uuid != NULL, FALSE);
|
||||
|
||||
priv->info_only = info_only;
|
||||
|
||||
nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv6 transaction (timeout in %d seconds)",
|
||||
priv->iface, priv->timeout);
|
||||
|
||||
|
|
@ -334,8 +389,9 @@ nm_dhcp_client_stop (NMDHCPClient *self)
|
|||
priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
|
||||
/* Kill the DHCP client */
|
||||
if (priv->pid > 0) {
|
||||
if (!priv->dead) {
|
||||
NM_DHCP_CLIENT_GET_CLASS (self)->stop (self);
|
||||
priv->dead = TRUE;
|
||||
|
||||
nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d",
|
||||
priv->iface, priv->pid);
|
||||
|
|
@ -344,7 +400,7 @@ nm_dhcp_client_stop (NMDHCPClient *self)
|
|||
/* And clean stuff up */
|
||||
|
||||
priv->pid = -1;
|
||||
priv->state = DHC_END;
|
||||
dhcp_client_set_state (self, DHC_END, FALSE, TRUE);
|
||||
|
||||
g_hash_table_remove_all (priv->options);
|
||||
|
||||
|
|
@ -390,11 +446,14 @@ static DhcState state_table[] = {
|
|||
{ DHC_REBIND4, "rebind" },
|
||||
{ DHC_REBIND6, "rebind6" },
|
||||
{ DHC_STOP, "stop" },
|
||||
{ DHC_STOP6, "stop6" },
|
||||
{ DHC_MEDIUM, "medium" },
|
||||
{ DHC_TIMEOUT, "timeout" },
|
||||
{ DHC_FAIL, "fail" },
|
||||
{ DHC_EXPIRE, "expire" },
|
||||
{ DHC_EXPIRE6, "expire6" },
|
||||
{ DHC_RELEASE, "release" },
|
||||
{ DHC_RELEASE6,"release6" },
|
||||
{ DHC_START, "start" },
|
||||
{ DHC_ABEND, "abend" },
|
||||
{ DHC_END, "end" },
|
||||
|
|
@ -512,70 +571,32 @@ nm_dhcp_client_new_options (NMDHCPClient *self,
|
|||
timeout_cleanup (self);
|
||||
}
|
||||
|
||||
priv->state = new_state;
|
||||
if (priv->ipv6) {
|
||||
nm_log_info (LOGD_DHCP6, "(%s): DHCPv6 state changed %s -> %s",
|
||||
priv->iface,
|
||||
state_to_string (old_state),
|
||||
state_to_string (priv->state));
|
||||
state_to_string (new_state));
|
||||
} else {
|
||||
nm_log_info (LOGD_DHCP4, "(%s): DHCPv4 state changed %s -> %s",
|
||||
priv->iface,
|
||||
state_to_string (old_state),
|
||||
state_to_string (priv->state));
|
||||
state_to_string (new_state));
|
||||
}
|
||||
|
||||
g_signal_emit (G_OBJECT (self),
|
||||
signals[STATE_CHANGED],
|
||||
0,
|
||||
priv->state);
|
||||
dhcp_client_set_state (self, new_state, TRUE, FALSE);
|
||||
}
|
||||
|
||||
#define NEW_TAG "new_"
|
||||
#define OLD_TAG "old_"
|
||||
|
||||
typedef struct {
|
||||
GHFunc func;
|
||||
gpointer user_data;
|
||||
} DhcpForeachInfo;
|
||||
|
||||
static void
|
||||
iterate_dhcp_config_option (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
DhcpForeachInfo *info = (DhcpForeachInfo *) user_data;
|
||||
char *tmp_key = NULL;
|
||||
const char **p;
|
||||
static const char *filter_options[] = {
|
||||
"interface", "pid", "reason", "dhcp_message_type", NULL
|
||||
};
|
||||
|
||||
/* Filter out stuff that's not actually new DHCP options */
|
||||
for (p = filter_options; *p; p++) {
|
||||
if (!strcmp (*p, (const char *) key))
|
||||
return;
|
||||
if (!strncmp ((const char *) key, OLD_TAG, strlen (OLD_TAG)))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove the "new_" prefix that dhclient passes back */
|
||||
if (!strncmp ((const char *) key, NEW_TAG, strlen (NEW_TAG)))
|
||||
tmp_key = g_strdup ((const char *) (key + strlen (NEW_TAG)));
|
||||
else
|
||||
tmp_key = g_strdup ((const char *) key);
|
||||
|
||||
(*info->func) ((gpointer) tmp_key, value, info->user_data);
|
||||
g_free (tmp_key);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dhcp_client_foreach_option (NMDHCPClient *self,
|
||||
GHFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDHCPClientPrivate *priv;
|
||||
DhcpForeachInfo info = { NULL, NULL };
|
||||
GHashTableIter iter;
|
||||
gpointer iterkey, itervalue;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE);
|
||||
|
|
@ -589,12 +610,35 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self,
|
|||
} else {
|
||||
nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
info.func = func;
|
||||
info.user_data = user_data;
|
||||
g_hash_table_foreach (priv->options, iterate_dhcp_config_option, &info);
|
||||
g_hash_table_iter_init (&iter, priv->options);
|
||||
while (g_hash_table_iter_next (&iter, &iterkey, &itervalue)) {
|
||||
const char *key = iterkey, *value = itervalue;
|
||||
const char **p;
|
||||
static const char *filter_options[] = {
|
||||
"interface", "pid", "reason", "dhcp_message_type", NULL
|
||||
};
|
||||
gboolean ignore = FALSE;
|
||||
|
||||
/* Filter out stuff that's not actually new DHCP options */
|
||||
for (p = filter_options; *p; p++) {
|
||||
if (!strcmp (*p, key) || !strncmp (key, OLD_TAG, strlen (OLD_TAG))) {
|
||||
ignore = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignore) {
|
||||
const char *tmp_key = value;
|
||||
|
||||
/* Remove the "new_" prefix that dhclient passes back */
|
||||
if (!strncmp (key, NEW_TAG, strlen (NEW_TAG)))
|
||||
tmp_key = key + strlen (NEW_TAG);
|
||||
|
||||
func ((gpointer) tmp_key, (gpointer) value, user_data);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -867,7 +911,12 @@ nm_dhcp_client_get_ip4_config (NMDHCPClient *self, gboolean test)
|
|||
priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
|
||||
if (test && !state_is_bound (priv->state)) {
|
||||
nm_log_warn (LOGD_DHCP4, "(%s): DHCP client didn't bind to a lease.", priv->iface);
|
||||
nm_log_warn (LOGD_DHCP4, "(%s): DHCPv4 client didn't bind to a lease.", priv->iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!g_hash_table_size (priv->options)) {
|
||||
/* We never got a response from the DHCP client */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -891,6 +940,8 @@ ip6_options_to_config (NMDHCPClient *self)
|
|||
struct in6_addr tmp_addr;
|
||||
NMIP6Address *addr = NULL;
|
||||
char *str = NULL;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL);
|
||||
|
|
@ -898,6 +949,12 @@ ip6_options_to_config (NMDHCPClient *self)
|
|||
priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
g_return_val_if_fail (priv->options != NULL, NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->options);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
nm_log_dbg (LOGD_DHCP6, "(%s): option '%s'=>'%s'",
|
||||
priv->iface, (const char *) key, (const char *) value);
|
||||
}
|
||||
|
||||
ip6_config = nm_ip6_config_new ();
|
||||
if (!ip6_config) {
|
||||
nm_log_warn (LOGD_DHCP6, "(%s): couldn't allocate memory for an IP6Config!", priv->iface);
|
||||
|
|
@ -911,27 +968,43 @@ ip6_options_to_config (NMDHCPClient *self)
|
|||
}
|
||||
|
||||
str = g_hash_table_lookup (priv->options, "new_ip6_address");
|
||||
if (str && (inet_pton (AF_INET6, str, &tmp_addr) > 0)) {
|
||||
if (str) {
|
||||
if (!inet_pton (AF_INET6, str, &tmp_addr)) {
|
||||
nm_log_warn (LOGD_DHCP6, "(%s): DHCP returned invalid address '%s'",
|
||||
priv->iface);
|
||||
goto error;
|
||||
}
|
||||
|
||||
nm_ip6_address_set_address (addr, &tmp_addr);
|
||||
nm_log_info (LOGD_DHCP6, " address %s", str);
|
||||
} else
|
||||
goto error;
|
||||
|
||||
str = g_hash_table_lookup (priv->options, "new_ip6_prefixlen");
|
||||
if (str) {
|
||||
long unsigned int prefix;
|
||||
|
||||
errno = 0;
|
||||
prefix = strtoul (str, NULL, 10);
|
||||
if (errno != 0 || prefix > 128)
|
||||
} else {
|
||||
/* No address in managed mode is a hard error */
|
||||
if (priv->info_only == FALSE)
|
||||
goto error;
|
||||
|
||||
nm_ip6_address_set_prefix (addr, (guint32) prefix);
|
||||
nm_log_info (LOGD_DHCP6, " prefix %lu", prefix);
|
||||
/* But "info-only" setups don't necessarily need an address */
|
||||
nm_ip6_address_unref (addr);
|
||||
addr = NULL;
|
||||
}
|
||||
|
||||
nm_ip6_config_take_address (ip6_config, addr);
|
||||
addr = NULL;
|
||||
/* Only care about prefix if we got an address */
|
||||
if (addr) {
|
||||
str = g_hash_table_lookup (priv->options, "new_ip6_prefixlen");
|
||||
if (str) {
|
||||
long unsigned int prefix;
|
||||
|
||||
errno = 0;
|
||||
prefix = strtoul (str, NULL, 10);
|
||||
if (errno != 0 || prefix > 128)
|
||||
goto error;
|
||||
|
||||
nm_ip6_address_set_prefix (addr, (guint32) prefix);
|
||||
nm_log_info (LOGD_DHCP6, " prefix %lu", prefix);
|
||||
}
|
||||
|
||||
nm_ip6_config_take_address (ip6_config, addr);
|
||||
addr = NULL;
|
||||
}
|
||||
|
||||
str = g_hash_table_lookup (priv->options, "new_host_name");
|
||||
if (str)
|
||||
|
|
@ -976,7 +1049,12 @@ nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test)
|
|||
priv = NM_DHCP_CLIENT_GET_PRIVATE (self);
|
||||
|
||||
if (test && !state_is_bound (priv->state)) {
|
||||
nm_log_warn (LOGD_DHCP6, "(%s): dhcp client didn't bind to a lease.", priv->iface);
|
||||
nm_log_warn (LOGD_DHCP6, "(%s): DHCPv6 client didn't bind to a lease.", priv->iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!g_hash_table_size (priv->options)) {
|
||||
/* We never got a response from the DHCP client */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1058,6 +1136,9 @@ dispose (GObject *object)
|
|||
* the DHCP client.
|
||||
*/
|
||||
|
||||
if (priv->remove_id)
|
||||
g_source_remove (priv->remove_id);
|
||||
|
||||
g_hash_table_destroy (priv->options);
|
||||
g_free (priv->iface);
|
||||
|
||||
|
|
@ -1128,5 +1209,14 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class)
|
|||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[REMOVE] =
|
||||
g_signal_new ("remove",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMDHCPClientClass, remove),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,11 +53,14 @@ typedef enum {
|
|||
DHC_REBIND6, /* IPv6 new/different lease */
|
||||
DHC_DEPREF6, /* IPv6 lease depreferred */
|
||||
DHC_STOP, /* remove old lease */
|
||||
DHC_STOP6, /* remove old lease */
|
||||
DHC_MEDIUM, /* media selection begun */
|
||||
DHC_TIMEOUT, /* timed out contacting DHCP server */
|
||||
DHC_FAIL, /* all attempts to contact server timed out, sleeping */
|
||||
DHC_EXPIRE, /* lease has expired, renewing */
|
||||
DHC_EXPIRE6, /* lease has expired, renewing */
|
||||
DHC_RELEASE, /* releasing lease */
|
||||
DHC_RELEASE6, /* releasing lease */
|
||||
DHC_START, /* sent when dhclient started OK */
|
||||
DHC_ABEND, /* dhclient exited abnormally */
|
||||
DHC_END, /* dhclient exited normally */
|
||||
|
|
@ -96,6 +99,7 @@ typedef struct {
|
|||
/* Signals */
|
||||
void (*state_changed) (NMDHCPClient *self, NMDHCPState state);
|
||||
void (*timeout) (NMDHCPClient *self);
|
||||
void (*remove) (NMDHCPClient *self);
|
||||
} NMDHCPClientClass;
|
||||
|
||||
GType nm_dhcp_client_get_type (void);
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ dhclient_start (NMDHCPClient *client,
|
|||
{
|
||||
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
|
||||
GPtrArray *argv = NULL;
|
||||
GPid pid = 0;
|
||||
GPid pid = -1;
|
||||
GError *error = NULL;
|
||||
const char *iface, *uuid;
|
||||
char *binary_name, *cmd_str;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_DHCPCD)
|
||||
G_DEFINE_TYPE (NMDHCPDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT)
|
||||
|
||||
#define NM_DHCP_DHCPCD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DHCP_DHCPCD, NMDHCPDhcpcdPrivate))
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ real_ip4_start (NMDHCPClient *client,
|
|||
{
|
||||
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
|
||||
GPtrArray *argv = NULL;
|
||||
GPid pid = 0;
|
||||
GPid pid = -1;
|
||||
GError *error = NULL;
|
||||
char *pid_contents = NULL, *binary_name, *cmd_str;
|
||||
const char *iface, *uuid, *hostname;
|
||||
|
|
@ -147,6 +147,7 @@ real_ip4_start (NMDHCPClient *client,
|
|||
&dhcpcd_child_setup, NULL, &pid, &error)) {
|
||||
nm_log_warn (LOGD_DHCP4, "dhcpcd failed to start. error: '%s'", error->message);
|
||||
g_error_free (error);
|
||||
pid = -1;
|
||||
} else
|
||||
nm_log_info (LOGD_DHCP4, "dhcpcd started with pid %d", pid);
|
||||
|
||||
|
|
|
|||
|
|
@ -235,19 +235,19 @@ nm_dhcp_manager_handle_event (DBusGProxy *proxy,
|
|||
|
||||
client = get_client_for_pid (manager, (GPid) temp);
|
||||
if (client == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "unhandled DHCP event for interface %s", iface);
|
||||
nm_log_warn (LOGD_DHCP, "(pid %d) unhandled DHCP event for interface %s", temp, iface);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (iface, nm_dhcp_client_get_iface (client))) {
|
||||
nm_log_warn (LOGD_DHCP, "received DHCP event from unexpected interface '%s' (expected '%s')",
|
||||
iface, nm_dhcp_client_get_iface (client));
|
||||
nm_log_warn (LOGD_DHCP, "(pid %d) received DHCP event from unexpected interface '%s' (expected '%s')",
|
||||
temp, iface, nm_dhcp_client_get_iface (client));
|
||||
goto out;
|
||||
}
|
||||
|
||||
reason = get_option (options, "reason");
|
||||
if (reason == NULL) {
|
||||
nm_log_warn (LOGD_DHCP, "DHCP event didn't have a reason");
|
||||
nm_log_warn (LOGD_DHCP, "(pid %d) DHCP event didn't have a reason", temp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -358,7 +358,7 @@ nm_dhcp_manager_new (const char *client, GError **error)
|
|||
return singleton;
|
||||
}
|
||||
|
||||
#define STATE_ID_TAG "state-id"
|
||||
#define REMOVE_ID_TAG "remove-id"
|
||||
#define TIMEOUT_ID_TAG "timeout-id"
|
||||
|
||||
static void
|
||||
|
|
@ -367,7 +367,7 @@ remove_client (NMDHCPManager *self, NMDHCPClient *client)
|
|||
NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
guint id;
|
||||
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (client), STATE_ID_TAG));
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (client), REMOVE_ID_TAG));
|
||||
if (id)
|
||||
g_signal_handler_disconnect (client, id);
|
||||
|
||||
|
|
@ -383,29 +383,16 @@ remove_client (NMDHCPManager *self, NMDHCPClient *client)
|
|||
g_hash_table_remove (priv->clients, client);
|
||||
}
|
||||
|
||||
static void
|
||||
client_state_changed (NMDHCPClient *client, NMDHCPState new_state, gpointer user_data)
|
||||
{
|
||||
if (new_state == DHC_ABEND || new_state == DHC_END)
|
||||
remove_client (NM_DHCP_MANAGER (user_data), client);
|
||||
}
|
||||
|
||||
static void
|
||||
client_timeout (NMDHCPClient *client, gpointer user_data)
|
||||
{
|
||||
remove_client (NM_DHCP_MANAGER (user_data), client);
|
||||
}
|
||||
|
||||
static void
|
||||
add_client (NMDHCPManager *self, NMDHCPClient *client)
|
||||
{
|
||||
NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
guint id;
|
||||
|
||||
id = g_signal_connect (client, "state-changed", G_CALLBACK (client_state_changed), self);
|
||||
g_object_set_data (G_OBJECT (client), STATE_ID_TAG, GUINT_TO_POINTER (id));
|
||||
id = g_signal_connect_swapped (client, "remove", G_CALLBACK (remove_client), self);
|
||||
g_object_set_data (G_OBJECT (client), REMOVE_ID_TAG, GUINT_TO_POINTER (id));
|
||||
|
||||
id = g_signal_connect (client, "timeout", G_CALLBACK (client_timeout), self);
|
||||
id = g_signal_connect_swapped (client, "timeout", G_CALLBACK (remove_client), self);
|
||||
g_object_set_data (G_OBJECT (client), TIMEOUT_ID_TAG, GUINT_TO_POINTER (id));
|
||||
|
||||
g_hash_table_insert (priv->clients, client, g_object_ref (client));
|
||||
|
|
@ -482,6 +469,13 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self,
|
|||
priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (s_ip4) {
|
||||
const char *method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (method) {
|
||||
/* Method must be 'auto' */
|
||||
g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL);
|
||||
}
|
||||
|
||||
if ( nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4)
|
||||
&& (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL)
|
||||
&& priv->hostname_provider != NULL) {
|
||||
|
|
|
|||
|
|
@ -11,14 +11,11 @@ noinst_LTLIBRARIES = libip6-manager.la
|
|||
|
||||
libip6_manager_la_SOURCES = \
|
||||
nm-ip6-manager.c \
|
||||
nm-ip6-manager.h \
|
||||
nm-netlink-listener.c \
|
||||
nm-netlink-listener.h
|
||||
nm-ip6-manager.h
|
||||
|
||||
libip6_manager_la_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(HAL_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED
|
||||
|
||||
libip6_manager_la_LIBADD = \
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_IP6_MANAGER_H
|
||||
|
|
@ -54,7 +54,7 @@ typedef struct {
|
|||
* that the initial configuration is complete.
|
||||
*/
|
||||
void (*addrconf_complete) (NMIP6Manager *manager,
|
||||
char *iface,
|
||||
guint32 ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success);
|
||||
|
||||
|
|
@ -63,22 +63,24 @@ typedef struct {
|
|||
* of the interface has changed.
|
||||
*/
|
||||
void (*config_changed) (NMIP6Manager *manager,
|
||||
char *iface,
|
||||
guint dhcp_opts);
|
||||
guint32 ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success);
|
||||
} NMIP6ManagerClass;
|
||||
|
||||
GType nm_ip6_manager_get_type (void);
|
||||
|
||||
NMIP6Manager *nm_ip6_manager_get (void);
|
||||
void nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
||||
const char *iface,
|
||||
NMSettingIP6Config *s_ip6);
|
||||
void nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
void nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
NMIP6Manager *nm_ip6_manager_get (void);
|
||||
void nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
||||
int ifindex,
|
||||
NMSettingIP6Config *s_ip6,
|
||||
const char *accept_ra_path);
|
||||
void nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
void nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
|
||||
NMIP6Config * nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
NMIP6Config * nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
|
||||
#endif /* NM_IP6_MANAGER_H */
|
||||
|
|
|
|||
|
|
@ -1,406 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2005 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*
|
||||
* Some code borrowed from HAL:
|
||||
*
|
||||
* Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
|
||||
* Copyright (C) 2004 Novell, Inc.
|
||||
*/
|
||||
|
||||
/* FIXME: this should be merged with src/nm-netlink-monitor.c */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "nm-system.h"
|
||||
#include "nm-netlink-listener.h"
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-netlink.h"
|
||||
|
||||
#define NM_NETLINK_LISTENER_EVENT_CONDITIONS \
|
||||
((GIOCondition) (G_IO_IN | G_IO_PRI))
|
||||
|
||||
#define NM_NETLINK_LISTENER_ERROR_CONDITIONS \
|
||||
((GIOCondition) (G_IO_ERR | G_IO_NVAL))
|
||||
|
||||
#define NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS \
|
||||
((GIOCondition) (G_IO_HUP))
|
||||
|
||||
#define NM_NETLINK_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
NM_TYPE_NETLINK_LISTENER, \
|
||||
NMNetlinkListenerPrivate))
|
||||
|
||||
typedef struct {
|
||||
struct nl_handle *nlh;
|
||||
struct nl_cb * nlh_cb;
|
||||
struct nl_cache * nlh_link_cache;
|
||||
|
||||
GIOChannel * io_channel;
|
||||
guint event_id;
|
||||
|
||||
guint request_status_id;
|
||||
} NMNetlinkListenerPrivate;
|
||||
|
||||
static gboolean nm_netlink_listener_event_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
gpointer user_data);
|
||||
|
||||
static gboolean nm_netlink_listener_error_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener);
|
||||
|
||||
static gboolean nm_netlink_listener_disconnect_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener);
|
||||
|
||||
static void close_connection (NMNetlinkListener *listener);
|
||||
|
||||
enum {
|
||||
NOTIFICATION = 0,
|
||||
ERROR,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (NMNetlinkListener, nm_netlink_listener, G_TYPE_OBJECT);
|
||||
|
||||
NMNetlinkListener *
|
||||
nm_netlink_listener_get (void)
|
||||
{
|
||||
static NMNetlinkListener *singleton = NULL;
|
||||
|
||||
if (!singleton)
|
||||
singleton = NM_NETLINK_LISTENER (g_object_new (NM_TYPE_NETLINK_LISTENER, NULL));
|
||||
else
|
||||
g_object_ref (singleton);
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_netlink_listener_init (NMNetlinkListener *listener)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (object);
|
||||
|
||||
if (priv->request_status_id)
|
||||
g_source_remove (priv->request_status_id);
|
||||
|
||||
if (priv->io_channel)
|
||||
close_connection (NM_NETLINK_LISTENER (object));
|
||||
|
||||
if (priv->nlh) {
|
||||
nl_handle_destroy (priv->nlh);
|
||||
priv->nlh = NULL;
|
||||
}
|
||||
|
||||
if (priv->nlh_cb) {
|
||||
nl_cb_put (priv->nlh_cb);
|
||||
priv->nlh_cb = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_netlink_listener_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_netlink_listener_class_init (NMNetlinkListenerClass *listener_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (listener_class);
|
||||
|
||||
g_type_class_add_private (listener_class, sizeof (NMNetlinkListenerPrivate));
|
||||
|
||||
/* Virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* Signals */
|
||||
signals[NOTIFICATION] =
|
||||
g_signal_new ("notification",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMNetlinkListenerClass, notification),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
|
||||
signals[ERROR] =
|
||||
g_signal_new ("error",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMNetlinkListenerClass, error),
|
||||
NULL, NULL, _nm_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static int
|
||||
netlink_event_input (struct nl_msg *msg, void *listener)
|
||||
{
|
||||
struct nlmsghdr *hdr = nlmsg_hdr (msg);
|
||||
|
||||
if (hdr->nlmsg_pid != 0)
|
||||
return NL_STOP;
|
||||
|
||||
g_signal_emit (listener, signals[NOTIFICATION], 0, msg);
|
||||
|
||||
/* Stop processing messages */
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
open_connection (NMNetlinkListener *listener, GError **error)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
int fd;
|
||||
GError *channel_error = NULL;
|
||||
GIOFlags channel_flags;
|
||||
|
||||
g_return_val_if_fail (priv->io_channel == NULL, FALSE);
|
||||
|
||||
priv->nlh_cb = nl_cb_alloc (NL_CB_DEFAULT);
|
||||
priv->nlh = nl_handle_alloc_cb (priv->nlh_cb);
|
||||
if (!priv->nlh) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_HANDLE,
|
||||
_("unable to allocate netlink handle: %s"),
|
||||
nl_geterror ());
|
||||
goto error;
|
||||
}
|
||||
|
||||
nl_disable_sequence_check (priv->nlh);
|
||||
nl_socket_modify_cb (priv->nlh, NL_CB_VALID, NL_CB_CUSTOM, netlink_event_input, listener);
|
||||
if (nl_connect (priv->nlh, NETLINK_ROUTE) < 0) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_CONNECT,
|
||||
_("unable to connect to netlink: %s"),
|
||||
nl_geterror ());
|
||||
goto error;
|
||||
}
|
||||
|
||||
fd = nl_socket_get_fd (priv->nlh);
|
||||
priv->io_channel = g_io_channel_unix_new (fd);
|
||||
|
||||
g_io_channel_set_encoding (priv->io_channel, NULL, &channel_error);
|
||||
/* Encoding is NULL, so no conversion error can possibly occur */
|
||||
g_assert (channel_error == NULL);
|
||||
|
||||
g_io_channel_set_close_on_unref (priv->io_channel, TRUE);
|
||||
channel_flags = g_io_channel_get_flags (priv->io_channel);
|
||||
channel_error = NULL;
|
||||
g_io_channel_set_flags (priv->io_channel,
|
||||
channel_flags | G_IO_FLAG_NONBLOCK,
|
||||
&channel_error);
|
||||
if (channel_error != NULL) {
|
||||
g_propagate_error (error, channel_error);
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->event_id = g_io_add_watch (priv->io_channel,
|
||||
(NM_NETLINK_LISTENER_EVENT_CONDITIONS |
|
||||
NM_NETLINK_LISTENER_ERROR_CONDITIONS |
|
||||
NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS),
|
||||
nm_netlink_listener_event_handler,
|
||||
listener);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
if (priv->io_channel)
|
||||
close_connection (listener);
|
||||
|
||||
if (priv->nlh) {
|
||||
nl_handle_destroy (priv->nlh);
|
||||
priv->nlh = NULL;
|
||||
}
|
||||
|
||||
if (priv->nlh_cb) {
|
||||
nl_cb_put (priv->nlh_cb);
|
||||
priv->nlh_cb = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
close_connection (NMNetlinkListener *listener)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
|
||||
g_return_if_fail (priv->io_channel != NULL);
|
||||
|
||||
if (priv->event_id) {
|
||||
g_source_remove (priv->event_id);
|
||||
priv->event_id = 0;
|
||||
}
|
||||
|
||||
g_io_channel_shutdown (priv->io_channel,
|
||||
TRUE /* flush pending data */,
|
||||
NULL);
|
||||
|
||||
g_io_channel_unref (priv->io_channel);
|
||||
priv->io_channel = NULL;
|
||||
}
|
||||
|
||||
GQuark
|
||||
nm_netlink_listener_error_quark (void)
|
||||
{
|
||||
static GQuark error_quark = 0;
|
||||
|
||||
if (error_quark == 0)
|
||||
error_quark = g_quark_from_static_string ("nm-netlink-listener-error-quark");
|
||||
|
||||
return error_quark;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_netlink_listener_subscribe (NMNetlinkListener *listener,
|
||||
int group,
|
||||
GError **error)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), FALSE);
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
|
||||
if (!priv->nlh) {
|
||||
if (!open_connection (listener, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nl_socket_add_membership (priv->nlh, group) < 0) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_JOIN_GROUP,
|
||||
_("unable to join netlink group: %s"),
|
||||
nl_geterror ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_netlink_listener_unsubscribe (NMNetlinkListener *listener, int group)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_NETLINK_LISTENER (listener));
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
g_return_if_fail (priv->nlh != NULL);
|
||||
|
||||
nl_socket_drop_membership (priv->nlh, group);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_event_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMNetlinkListener *listener = (NMNetlinkListener *) user_data;
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), TRUE);
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
g_return_val_if_fail (priv->event_id > 0, TRUE);
|
||||
|
||||
if (io_condition & NM_NETLINK_LISTENER_ERROR_CONDITIONS)
|
||||
return nm_netlink_listener_error_handler (channel, io_condition, listener);
|
||||
else if (io_condition & NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS)
|
||||
return nm_netlink_listener_disconnect_handler (channel, io_condition, listener);
|
||||
|
||||
g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_LISTENER_EVENT_CONDITIONS)), FALSE);
|
||||
|
||||
if (nl_recvmsgs_default (priv->nlh) < 0) {
|
||||
error = g_error_new (NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_PROCESSING_MESSAGE,
|
||||
_("error processing netlink message: %s"),
|
||||
nl_geterror ());
|
||||
|
||||
g_signal_emit (G_OBJECT (listener),
|
||||
signals[ERROR],
|
||||
0, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_error_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener)
|
||||
{
|
||||
GError *socket_error;
|
||||
const char *err_msg;
|
||||
int err_code;
|
||||
socklen_t err_len;
|
||||
|
||||
g_return_val_if_fail (io_condition & NM_NETLINK_LISTENER_ERROR_CONDITIONS, FALSE);
|
||||
|
||||
err_code = 0;
|
||||
err_len = sizeof (err_code);
|
||||
if (getsockopt (g_io_channel_unix_get_fd (channel),
|
||||
SOL_SOCKET, SO_ERROR, (void *) &err_code, &err_len))
|
||||
err_msg = strerror (err_code);
|
||||
else
|
||||
err_msg = _("error occurred while waiting for data on socket");
|
||||
|
||||
socket_error = g_error_new (NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_WAITING_FOR_SOCKET_DATA,
|
||||
"%s",
|
||||
err_msg);
|
||||
|
||||
g_signal_emit (G_OBJECT (listener),
|
||||
signals[ERROR],
|
||||
0, socket_error);
|
||||
|
||||
g_error_free (socket_error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_disconnect_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener)
|
||||
{
|
||||
|
||||
g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS)), FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Netlink socket listener
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2005 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef NM_NETLINK_LISTENER_H
|
||||
#define NM_NETLINK_LISTENER_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-netlink.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_NETLINK_LISTENER (nm_netlink_listener_get_type ())
|
||||
#define NM_NETLINK_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_LISTENER, NMNetlinkListener))
|
||||
#define NM_NETLINK_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NETLINK_LISTENER, NMNetlinkListenerClass))
|
||||
#define NM_IS_NETLINK_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_LISTENER))
|
||||
#define NM_IS_NETLINK_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NETLINK_LISTENER))
|
||||
#define NM_NETLINK_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_NETLINK_LISTENER, NMNetlinkListenerClass))
|
||||
#define NM_NETLINK_LISTENER_ERROR (nm_netlink_listener_error_quark ())
|
||||
|
||||
typedef enum {
|
||||
NM_NETLINK_LISTENER_ERROR_GENERIC = 0,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_HANDLE,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_CONNECT,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_JOIN_GROUP,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_LINK_CACHE,
|
||||
NM_NETLINK_LISTENER_ERROR_PROCESSING_MESSAGE,
|
||||
NM_NETLINK_LISTENER_ERROR_BAD_ALLOC,
|
||||
NM_NETLINK_LISTENER_ERROR_WAITING_FOR_SOCKET_DATA,
|
||||
NM_NETLINK_LISTENER_ERROR_LINK_CACHE_UPDATE
|
||||
} NMNetlinkListenerError;
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} NMNetlinkListener;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*notification) (NMNetlinkListener *listener, struct nl_msg *msg);
|
||||
void (*error) (NMNetlinkListener *listener, GError *error);
|
||||
} NMNetlinkListenerClass;
|
||||
|
||||
GType nm_netlink_listener_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_listener_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
NMNetlinkListener *nm_netlink_listener_get (void);
|
||||
|
||||
gboolean nm_netlink_listener_subscribe (NMNetlinkListener *listener,
|
||||
int group,
|
||||
GError **error);
|
||||
void nm_netlink_listener_unsubscribe (NMNetlinkListener *listener,
|
||||
int group);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_NETLINK_LISTENER_H */
|
||||
|
|
@ -10,5 +10,6 @@ libnm_logging_la_CPPFLAGS = \
|
|||
-DG_DISABLE_DEPRECATED
|
||||
|
||||
libnm_logging_la_LIBADD = \
|
||||
-ldl \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,36 @@ nm_logging_setup (const char *level, const char *domains, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_logging_level_to_string (void)
|
||||
{
|
||||
const LogDesc *diter;
|
||||
|
||||
for (diter = &level_descs[0]; diter->name; diter++) {
|
||||
if (diter->num == log_level)
|
||||
return diter->name;
|
||||
}
|
||||
g_warn_if_reached ();
|
||||
return "";
|
||||
}
|
||||
|
||||
char *
|
||||
nm_logging_domains_to_string (void)
|
||||
{
|
||||
const LogDesc *diter;
|
||||
GString *str;
|
||||
|
||||
str = g_string_sized_new (75);
|
||||
for (diter = &domain_descs[0]; diter->name; diter++) {
|
||||
if (diter->num & log_domains) {
|
||||
if (str->len)
|
||||
g_string_append_c (str, ',');
|
||||
g_string_append (str, diter->name);
|
||||
}
|
||||
}
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
void _nm_log (const char *loc,
|
||||
const char *func,
|
||||
guint32 domain,
|
||||
|
|
@ -330,9 +360,9 @@ void
|
|||
nm_logging_start (gboolean become_daemon)
|
||||
{
|
||||
if (become_daemon)
|
||||
openlog (G_LOG_DOMAIN, 0, LOG_DAEMON);
|
||||
openlog (G_LOG_DOMAIN, LOG_PID, LOG_DAEMON);
|
||||
else
|
||||
openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR, LOG_USER);
|
||||
openlog (G_LOG_DOMAIN, LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER);
|
||||
|
||||
g_log_set_handler (G_LOG_DOMAIN,
|
||||
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ void _nm_log (const char *loc, const char *func,
|
|||
guint32 domain, guint32 level,
|
||||
const char *fmt, ...);
|
||||
|
||||
const char *nm_logging_level_to_string (void);
|
||||
char *nm_logging_domains_to_string (void);
|
||||
|
||||
/* Undefine the nm-utils.h logging stuff to ensure errors */
|
||||
#undef nm_print_backtrace
|
||||
#undef nm_get_timestamp
|
||||
|
|
|
|||
|
|
@ -661,7 +661,8 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
|
|||
case MM_MODEM_IP_METHOD_STATIC:
|
||||
case MM_MODEM_IP_METHOD_DHCP:
|
||||
iface = nm_device_get_ip_iface (device);
|
||||
nm_system_device_flush_routes_with_iface (iface);
|
||||
/* FIXME: use AF_UNSPEC here when we have IPv6 support */
|
||||
nm_system_device_flush_routes_with_iface (iface, AF_INET);
|
||||
nm_system_device_flush_addresses_with_iface (iface);
|
||||
nm_system_device_set_up_down_with_iface (iface, FALSE, NULL);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "nm-named-manager.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-ip6-config.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-system.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -60,8 +61,10 @@ G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
|
|||
|
||||
|
||||
struct NMNamedManagerPrivate {
|
||||
NMIP4Config *vpn_config;
|
||||
NMIP4Config *device_config;
|
||||
NMIP4Config *ip4_vpn_config;
|
||||
NMIP4Config *ip4_device_config;
|
||||
NMIP6Config *ip6_vpn_config;
|
||||
NMIP6Config *ip6_device_config;
|
||||
GSList *configs;
|
||||
};
|
||||
|
||||
|
|
@ -97,6 +100,26 @@ typedef struct {
|
|||
GPtrArray *searches;
|
||||
} NMResolvConfData;
|
||||
|
||||
static void
|
||||
add_string_item (GPtrArray *array, const char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (str != NULL);
|
||||
|
||||
/* Check for dupes before adding */
|
||||
for (i = 0; i < array->len; i++) {
|
||||
const char *candidate = g_ptr_array_index (array, i);
|
||||
|
||||
if (candidate && !strcmp (candidate, str))
|
||||
return;
|
||||
}
|
||||
|
||||
/* No dupes, add the new item */
|
||||
g_ptr_array_add (array, g_strdup (str));
|
||||
}
|
||||
|
||||
static void
|
||||
merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src)
|
||||
{
|
||||
|
|
@ -109,19 +132,22 @@ merge_one_ip4_config (NMResolvConfData *rc, NMIP4Config *src)
|
|||
|
||||
addr.s_addr = nm_ip4_config_get_nameserver (src, i);
|
||||
if (inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN) > 0)
|
||||
g_ptr_array_add (rc->nameservers, g_strdup (buf));
|
||||
add_string_item (rc->nameservers, buf);
|
||||
}
|
||||
|
||||
num = nm_ip4_config_get_num_domains (src);
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *domain;
|
||||
|
||||
domain = nm_ip4_config_get_domain (src, i);
|
||||
if (!rc->domain)
|
||||
rc->domain = nm_ip4_config_get_domain (src, i);
|
||||
g_ptr_array_add (rc->searches, g_strdup (nm_ip4_config_get_domain (src, i)));
|
||||
rc->domain = domain;
|
||||
add_string_item (rc->searches, domain);
|
||||
}
|
||||
|
||||
num = nm_ip4_config_get_num_searches (src);
|
||||
for (i = 0; i < num; i++)
|
||||
g_ptr_array_add (rc->searches, g_strdup (nm_ip4_config_get_search (src, i)));
|
||||
add_string_item (rc->searches, nm_ip4_config_get_search (src, i));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -139,23 +165,26 @@ merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src)
|
|||
/* inet_ntop is probably supposed to do this for us, but it doesn't */
|
||||
if (IN6_IS_ADDR_V4MAPPED (addr)) {
|
||||
if (inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, INET_ADDRSTRLEN) > 0)
|
||||
g_ptr_array_add (rc->nameservers, g_strdup (buf));
|
||||
add_string_item (rc->nameservers, buf);
|
||||
} else {
|
||||
if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0)
|
||||
g_ptr_array_add (rc->nameservers, g_strdup (buf));
|
||||
add_string_item (rc->nameservers, buf);
|
||||
}
|
||||
}
|
||||
|
||||
num = nm_ip6_config_get_num_domains (src);
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *domain;
|
||||
|
||||
domain = nm_ip6_config_get_domain (src, i);
|
||||
if (!rc->domain)
|
||||
rc->domain = nm_ip6_config_get_domain (src, i);
|
||||
g_ptr_array_add (rc->searches, g_strdup (nm_ip6_config_get_domain (src, i)));
|
||||
rc->domain = domain;
|
||||
add_string_item (rc->searches, domain);
|
||||
}
|
||||
|
||||
num = nm_ip6_config_get_num_searches (src);
|
||||
for (i = 0; i < num; i++)
|
||||
g_ptr_array_add (rc->searches, g_strdup (nm_ip6_config_get_search (src, i)));
|
||||
add_string_item (rc->searches, nm_ip6_config_get_search (src, i));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -487,25 +516,33 @@ rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
|||
rc.domain = NULL;
|
||||
rc.searches = g_ptr_array_new ();
|
||||
|
||||
if (priv->vpn_config)
|
||||
merge_one_ip4_config (&rc, priv->vpn_config);
|
||||
if (priv->ip4_vpn_config)
|
||||
merge_one_ip4_config (&rc, priv->ip4_vpn_config);
|
||||
if (priv->ip4_device_config)
|
||||
merge_one_ip4_config (&rc, priv->ip4_device_config);
|
||||
|
||||
if (priv->device_config)
|
||||
merge_one_ip4_config (&rc, priv->device_config);
|
||||
if (priv->ip6_vpn_config)
|
||||
merge_one_ip6_config (&rc, priv->ip6_vpn_config);
|
||||
if (priv->ip6_device_config)
|
||||
merge_one_ip6_config (&rc, priv->ip6_device_config);
|
||||
|
||||
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
|
||||
if ( (iter->data == priv->ip4_vpn_config)
|
||||
|| (iter->data == priv->ip4_device_config)
|
||||
|| (iter->data == priv->ip6_vpn_config)
|
||||
|| (iter->data == priv->ip6_device_config))
|
||||
continue;
|
||||
|
||||
if (NM_IS_IP4_CONFIG (iter->data)) {
|
||||
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
|
||||
|
||||
if ((config == priv->vpn_config) || (config == priv->device_config))
|
||||
continue;
|
||||
|
||||
merge_one_ip4_config (&rc, config);
|
||||
} else {
|
||||
} else if (NM_IS_IP6_CONFIG (iter->data)) {
|
||||
NMIP6Config *config = NM_IP6_CONFIG (iter->data);
|
||||
|
||||
merge_one_ip6_config (&rc, config);
|
||||
}
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
domain = rc.domain;
|
||||
|
|
@ -572,10 +609,10 @@ nm_named_manager_add_ip4_config (NMNamedManager *mgr,
|
|||
|
||||
switch (cfg_type) {
|
||||
case NM_NAMED_IP_CONFIG_TYPE_VPN:
|
||||
priv->vpn_config = config;
|
||||
priv->ip4_vpn_config = config;
|
||||
break;
|
||||
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
|
||||
priv->device_config = config;
|
||||
priv->ip4_device_config = config;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -613,11 +650,10 @@ nm_named_manager_remove_ip4_config (NMNamedManager *mgr,
|
|||
|
||||
priv->configs = g_slist_remove (priv->configs, config);
|
||||
|
||||
if (config == priv->vpn_config)
|
||||
priv->vpn_config = NULL;
|
||||
|
||||
if (config == priv->device_config)
|
||||
priv->device_config = NULL;
|
||||
if (config == priv->ip4_vpn_config)
|
||||
priv->ip4_vpn_config = NULL;
|
||||
if (config == priv->ip4_device_config)
|
||||
priv->ip4_device_config = NULL;
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
|
|
@ -643,10 +679,21 @@ nm_named_manager_add_ip6_config (NMNamedManager *mgr,
|
|||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
g_return_val_if_fail (cfg_type == NM_NAMED_IP_CONFIG_TYPE_DEFAULT, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
switch (cfg_type) {
|
||||
case NM_NAMED_IP_CONFIG_TYPE_VPN:
|
||||
/* FIXME: not quite yet... */
|
||||
g_return_val_if_fail (cfg_type != NM_NAMED_IP_CONFIG_TYPE_VPN, FALSE);
|
||||
priv->ip6_vpn_config = config;
|
||||
break;
|
||||
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
|
||||
priv->ip6_device_config = config;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't allow the same zone added twice */
|
||||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
|
@ -679,6 +726,11 @@ nm_named_manager_remove_ip6_config (NMNamedManager *mgr,
|
|||
|
||||
priv->configs = g_slist_remove (priv->configs, config);
|
||||
|
||||
if (config == priv->ip6_vpn_config)
|
||||
priv->ip6_vpn_config = NULL;
|
||||
if (config == priv->ip6_device_config)
|
||||
priv->ip6_device_config = NULL;
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ typedef struct {
|
|||
|
||||
NMActiveConnectionState state;
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
gboolean shared;
|
||||
GSList *share_rules;
|
||||
|
||||
|
|
@ -88,6 +89,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
PROP_VPN,
|
||||
|
||||
LAST_PROP
|
||||
|
|
@ -104,7 +106,7 @@ device_state_changed (NMDevice *device,
|
|||
NMActRequest *self = NM_ACT_REQUEST (user_data);
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
NMActiveConnectionState new_ac_state;
|
||||
gboolean new_default = FALSE;
|
||||
gboolean new_default = FALSE, new_default6 = FALSE;
|
||||
|
||||
/* Set NMActiveConnection state based on the device's state */
|
||||
switch (new_state) {
|
||||
|
|
@ -117,6 +119,7 @@ device_state_changed (NMDevice *device,
|
|||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
|
||||
new_default = priv->is_default;
|
||||
new_default6 = priv->is_default6;
|
||||
break;
|
||||
default:
|
||||
new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
|
||||
|
|
@ -132,6 +135,11 @@ device_state_changed (NMDevice *device,
|
|||
priv->is_default = new_default;
|
||||
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
|
||||
}
|
||||
|
||||
if (new_default6 != priv->is_default6) {
|
||||
priv->is_default6 = new_default6;
|
||||
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
|
||||
}
|
||||
}
|
||||
|
||||
NMActRequest *
|
||||
|
|
@ -271,6 +279,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, priv->is_default);
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, priv->is_default6);
|
||||
break;
|
||||
case PROP_VPN:
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
|
|
@ -334,7 +345,14 @@ nm_act_request_class_init (NMActRequestClass *req_class)
|
|||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
|
|
@ -548,6 +566,29 @@ nm_act_request_get_default (NMActRequest *req)
|
|||
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6)
|
||||
{
|
||||
NMActRequestPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (req));
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (req);
|
||||
if (priv->is_default6 == is_default6)
|
||||
return;
|
||||
|
||||
priv->is_default6 = is_default6;
|
||||
g_object_notify (G_OBJECT (req), NM_ACTIVE_CONNECTION_DEFAULT6);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_act_request_get_default6 (NMActRequest *req)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
|
||||
|
||||
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6;
|
||||
}
|
||||
|
||||
static void
|
||||
share_child_setup (gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 2005 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2005 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_ACTIVATION_REQUEST_H
|
||||
|
|
@ -76,6 +76,10 @@ void nm_act_request_set_default (NMActRequest *req, gboolean is_default
|
|||
|
||||
gboolean nm_act_request_get_default (NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6);
|
||||
|
||||
gboolean nm_act_request_get_default6 (NMActRequest *req);
|
||||
|
||||
gboolean nm_act_request_get_shared (NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_shared (NMActRequest *req, gboolean shared);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_ACTIVE_CONNECTION_H
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
|
||||
#define NM_ACTIVE_CONNECTION_STATE "state"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6"
|
||||
#define NM_ACTIVE_CONNECTION_VPN "vpn"
|
||||
|
||||
char *nm_active_connection_get_next_object_path (void);
|
||||
|
|
|
|||
|
|
@ -275,10 +275,16 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
|
|||
case NM_DEVICE_STATE_PREPARE:
|
||||
case NM_DEVICE_STATE_CONFIG:
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||
break;
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
if (nm_device_ip_config_should_fail (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include <linux/if.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <netlink/route/addr.h>
|
||||
|
||||
#include "nm-glib-compat.h"
|
||||
#include "nm-device-ethernet.h"
|
||||
#include "nm-device-interface.h"
|
||||
|
|
@ -43,7 +45,6 @@
|
|||
#include "nm-supplicant-manager.h"
|
||||
#include "nm-supplicant-interface.h"
|
||||
#include "nm-supplicant-config.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-system.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -105,7 +106,6 @@ typedef struct {
|
|||
|
||||
struct ether_addr hw_addr;
|
||||
gboolean carrier;
|
||||
guint32 ifindex;
|
||||
|
||||
NMNetlinkMonitor * monitor;
|
||||
gulong link_connected_id;
|
||||
|
|
@ -133,7 +133,6 @@ enum {
|
|||
PROP_HW_ADDRESS,
|
||||
PROP_SPEED,
|
||||
PROP_CARRIER,
|
||||
PROP_IFINDEX,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -246,11 +245,10 @@ carrier_on (NMNetlinkMonitor *monitor,
|
|||
{
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
guint32 caps;
|
||||
|
||||
/* Make sure signal is for us */
|
||||
if (idx == priv->ifindex) {
|
||||
if (idx == nm_device_get_ifindex (device)) {
|
||||
/* Ignore spurious netlink messages */
|
||||
caps = nm_device_get_capabilities (device);
|
||||
if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
|
||||
|
|
@ -267,11 +265,10 @@ carrier_off (NMNetlinkMonitor *monitor,
|
|||
{
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
guint32 caps;
|
||||
|
||||
/* Make sure signal is for us */
|
||||
if (idx == priv->ifindex) {
|
||||
if (idx == nm_device_get_ifindex (device)) {
|
||||
NMDeviceState state;
|
||||
gboolean defer = FALSE;
|
||||
|
||||
|
|
@ -312,7 +309,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
caps = nm_device_get_capabilities (self);
|
||||
if (caps & NM_DEVICE_CAP_CARRIER_DETECT) {
|
||||
|
|
@ -331,7 +329,7 @@ constructor (GType type,
|
|||
|
||||
/* Get initial link state */
|
||||
if (!nm_netlink_monitor_get_flags_sync (priv->monitor,
|
||||
priv->ifindex,
|
||||
nm_device_get_ifindex (NM_DEVICE (self)),
|
||||
&ifflags,
|
||||
&error)) {
|
||||
nm_log_warn (LOGD_HW | LOGD_ETHER,
|
||||
|
|
@ -426,8 +424,7 @@ real_hw_take_down (NMDevice *dev)
|
|||
NMDevice *
|
||||
nm_device_ethernet_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
g_return_val_if_fail (udi != NULL, NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
|
@ -437,7 +434,6 @@ nm_device_ethernet_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_ETHERNET_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "Ethernet",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET,
|
||||
NULL);
|
||||
|
|
@ -459,14 +455,6 @@ nm_device_ethernet_get_address (NMDeviceEthernet *self, struct ether_addr *addr)
|
|||
memcpy (addr, &(NM_DEVICE_ETHERNET_GET_PRIVATE (self)->hw_addr), sizeof (struct ether_addr));
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_device_ethernet_get_ifindex (NMDeviceEthernet *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
/* Returns speed in Mb/s */
|
||||
static guint32
|
||||
nm_device_ethernet_get_speed (NMDeviceEthernet *self)
|
||||
|
|
@ -1618,7 +1606,7 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
|
|||
int ifindex;
|
||||
AddrData check_data;
|
||||
|
||||
ifindex = nm_device_ethernet_get_ifindex (NM_DEVICE_ETHERNET (self));
|
||||
ifindex = nm_device_get_ifindex (self);
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
|
@ -1790,9 +1778,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_CARRIER:
|
||||
g_value_set_boolean (value, priv->carrier);
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, priv->ifindex);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1803,13 +1788,7 @@ static void
|
|||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1876,14 +1855,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_ETHERNET_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
/* Signals */
|
||||
signals[PROPERTIES_CHANGED] =
|
||||
nm_properties_changed_signal_new (object_class,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address"
|
||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
|
||||
#define NM_DEVICE_ETHERNET_IFINDEX "ifindex"
|
||||
|
||||
typedef struct {
|
||||
NMDevice parent;
|
||||
|
|
@ -58,14 +57,11 @@ GType nm_device_ethernet_get_type (void);
|
|||
|
||||
NMDevice *nm_device_ethernet_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
const char *driver);
|
||||
|
||||
void nm_device_ethernet_get_address (NMDeviceEthernet *dev,
|
||||
struct ether_addr *addr);
|
||||
|
||||
guint32 nm_device_ethernet_get_ifindex (NMDeviceEthernet *dev);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_DEVICE_ETHERNET_H */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-marshal.h"
|
||||
|
|
@ -186,6 +186,14 @@ nm_device_interface_init (gpointer g_iface)
|
|||
RFKILL_TYPE_UNKNOWN,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
g_object_interface_install_property
|
||||
(g_iface,
|
||||
g_param_spec_int (NM_DEVICE_INTERFACE_IFINDEX,
|
||||
"Ifindex",
|
||||
"Ifindex",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
/* Signals */
|
||||
g_signal_new ("state-changed",
|
||||
iface_type,
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ typedef enum
|
|||
#define NM_DEVICE_INTERFACE_STATE "state"
|
||||
#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
|
||||
#define NM_DEVICE_INTERFACE_MANAGED "managed"
|
||||
#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */
|
||||
|
||||
typedef enum {
|
||||
NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000,
|
||||
|
|
@ -77,6 +78,7 @@ typedef enum {
|
|||
NM_DEVICE_INTERFACE_PROP_MANAGED,
|
||||
NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
|
||||
NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE,
|
||||
NM_DEVICE_INTERFACE_PROP_IFINDEX,
|
||||
} NMDeviceInterfaceProp;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -72,10 +72,16 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
|
|||
case NM_DEVICE_STATE_PREPARE:
|
||||
case NM_DEVICE_STATE_CONFIG:
|
||||
case NM_DEVICE_STATE_NEED_AUTH:
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
|
||||
break;
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
if (nm_device_ip_config_should_fail (device, FALSE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ enum {
|
|||
PROP_HW_ADDRESS,
|
||||
PROP_COMPANION,
|
||||
PROP_ACTIVE_CHANNEL,
|
||||
PROP_IFINDEX,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -98,7 +97,6 @@ struct _NMDeviceOlpcMeshPrivate
|
|||
gboolean dispose_has_run;
|
||||
|
||||
struct ether_addr hw_addr;
|
||||
guint32 ifindex;
|
||||
|
||||
GByteArray * ssid;
|
||||
|
||||
|
|
@ -263,7 +261,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
|
|
@ -539,15 +538,6 @@ nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid)
|
|||
close (sk);
|
||||
}
|
||||
|
||||
|
||||
guint32
|
||||
nm_device_olpc_mesh_get_ifindex (NMDeviceOlpcMesh *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -647,15 +637,6 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
NMIP4Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
|
|
@ -701,9 +682,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_ACTIVE_CHANNEL:
|
||||
g_value_set_uint (value, nm_device_olpc_mesh_get_channel (device));
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, nm_device_olpc_mesh_get_ifindex (device));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -714,13 +692,7 @@ static void
|
|||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -753,7 +725,6 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
|
|||
|
||||
parent_class->act_stage1_prepare = real_act_stage1_prepare;
|
||||
parent_class->act_stage2_config = real_act_stage2_config;
|
||||
parent_class->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout;
|
||||
|
||||
/* Properties */
|
||||
g_object_class_install_property
|
||||
|
|
@ -780,13 +751,6 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
|
|||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_OLPC_MESH_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
signals[PROPERTIES_CHANGED] =
|
||||
nm_properties_changed_signal_new (object_class,
|
||||
G_STRUCT_OFFSET (NMDeviceOlpcMeshClass, properties_changed));
|
||||
|
|
@ -986,8 +950,7 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
|
|||
NMDevice *
|
||||
nm_device_olpc_mesh_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
GObject *obj;
|
||||
|
||||
|
|
@ -999,7 +962,6 @@ nm_device_olpc_mesh_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_OLPC_MESH_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 OLPC Mesh",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_OLPC_MESH_COMPANION "companion"
|
||||
#define NM_DEVICE_OLPC_MESH_BITRATE "bitrate"
|
||||
#define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel"
|
||||
#define NM_DEVICE_OLPC_MESH_IFINDEX "ifindex"
|
||||
|
||||
#ifndef NM_DEVICE_OLPC_MESH_DEFINED
|
||||
#define NM_DEVICE_OLPC_MESH_DEFINED
|
||||
|
|
@ -75,10 +74,7 @@ GType nm_device_olpc_mesh_get_type (void);
|
|||
|
||||
NMDevice *nm_device_olpc_mesh_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
|
||||
guint32 nm_device_olpc_mesh_get_ifindex (NMDeviceOlpcMesh *self);
|
||||
const char *driver);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -40,4 +40,6 @@ void nm_device_handle_autoip4_event (NMDevice *self,
|
|||
const char *event,
|
||||
const char *address);
|
||||
|
||||
gboolean nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6);
|
||||
|
||||
#endif /* NM_DEVICE_PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ enum {
|
|||
PROP_BITRATE,
|
||||
PROP_ACTIVE_ACCESS_POINT,
|
||||
PROP_CAPABILITIES,
|
||||
PROP_IFINDEX,
|
||||
PROP_SCANNING,
|
||||
PROP_IPW_RFKILL_STATE,
|
||||
|
||||
|
|
@ -144,7 +143,6 @@ struct _NMDeviceWifiPrivate {
|
|||
gboolean disposed;
|
||||
|
||||
struct ether_addr hw_addr;
|
||||
guint32 ifindex;
|
||||
|
||||
/* Legacy rfkill for ipw2x00; will be fixed with 2.6.33 kernel */
|
||||
char * ipw_rfkill_path;
|
||||
|
|
@ -579,7 +577,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_WIFI, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
memset (&range, 0, sizeof (struct iw_range));
|
||||
success = wireless_get_range (NM_DEVICE_WIFI (object), &range, &response_len);
|
||||
|
|
@ -2677,7 +2676,11 @@ handle_auth_or_fail (NMDeviceWifi *self,
|
|||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
if (!req) {
|
||||
req = nm_device_get_act_request (NM_DEVICE (self));
|
||||
g_assert (req);
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
|
@ -3188,21 +3191,19 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
|
|||
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
NMIP4Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
handle_ip_config_timeout (NMDeviceWifi *self,
|
||||
NMConnection *connection,
|
||||
gboolean may_fail,
|
||||
gboolean *chain_up,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self);
|
||||
NMAccessPoint *ap;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMIP4Config *real_config = NULL;
|
||||
NMActRequest *req = nm_device_get_act_request (dev);
|
||||
NMConnection *connection;
|
||||
gboolean auth_enforced = FALSE, encrypted = FALSE;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
ap = nm_device_wifi_get_activation_ap (self);
|
||||
g_assert (ap);
|
||||
|
||||
/* If nothing checks the security authentication information (as in
|
||||
|
|
@ -3210,9 +3211,8 @@ real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
|||
* the encryption key is likely wrong. Ask the user for a new one.
|
||||
* Otherwise the failure likely happened after a successful authentication.
|
||||
*/
|
||||
connection = nm_act_request_get_connection (req);
|
||||
auth_enforced = ap_auth_enforced (connection, ap, &encrypted);
|
||||
if (encrypted && !auth_enforced) {
|
||||
if (encrypted && !auth_enforced && !may_fail) {
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
||||
|
|
@ -3221,39 +3221,83 @@ real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
|||
nm_log_warn (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless): could not get IP configuration for "
|
||||
"connection '%s'.",
|
||||
nm_device_get_iface (dev), nm_setting_connection_get_id (s_con));
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_setting_connection_get_id (s_con));
|
||||
|
||||
ret = handle_auth_or_fail (self, req, TRUE);
|
||||
ret = handle_auth_or_fail (self, NULL, TRUE);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless): asking for new secrets",
|
||||
nm_device_get_iface (dev));
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
} else {
|
||||
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
|
||||
}
|
||||
} else if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) {
|
||||
NMDeviceWifiClass *klass;
|
||||
NMDeviceClass * parent_class;
|
||||
|
||||
/* For Ad-Hoc networks, chain up to parent to get a Zeroconf IP */
|
||||
klass = NM_DEVICE_WIFI_GET_CLASS (self);
|
||||
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
|
||||
ret = parent_class->act_stage4_ip4_config_timeout (dev, &real_config, reason);
|
||||
} else {
|
||||
/* Non-encrypted network or authentication is enforced by some
|
||||
* entity (AP, RADIUS server, etc), but IP configure failed. Alert
|
||||
* the user.
|
||||
* entity (AP, RADIUS server, etc), but IP configure failed. Let the
|
||||
* superclass handle it.
|
||||
*/
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
*chain_up = TRUE;
|
||||
}
|
||||
|
||||
*config = real_config;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip4_config_timeout (NMDevice *dev,
|
||||
NMIP4Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
gboolean may_fail = FALSE, chain_up = FALSE;
|
||||
NMActStageReturn ret;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (s_ip4)
|
||||
may_fail = nm_setting_ip4_config_get_may_fail (s_ip4);
|
||||
|
||||
ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason);
|
||||
if (chain_up)
|
||||
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip4_config_timeout (dev, config, reason);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_ip6_config_timeout (NMDevice *dev,
|
||||
NMIP6Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean may_fail = FALSE, chain_up = FALSE;
|
||||
NMActStageReturn ret;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6)
|
||||
may_fail = nm_setting_ip6_config_get_may_fail (s_ip6);
|
||||
|
||||
ret = handle_ip_config_timeout (NM_DEVICE_WIFI (dev), connection, may_fail, &chain_up, reason);
|
||||
if (chain_up)
|
||||
ret = NM_DEVICE_CLASS (nm_device_wifi_parent_class)->act_stage4_ip6_config_timeout (dev, config, reason);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
activation_success_handler (NMDevice *dev)
|
||||
{
|
||||
|
|
@ -3462,14 +3506,6 @@ device_state_changed (NMDevice *device,
|
|||
remove_all_aps (self);
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_device_wifi_get_ifindex (NMDeviceWifi *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_WIFI_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
NMAccessPoint *
|
||||
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
|
||||
{
|
||||
|
|
@ -3563,8 +3599,7 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
|||
NMDevice *
|
||||
nm_device_wifi_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
g_return_val_if_fail (udi != NULL, NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
|
@ -3574,7 +3609,6 @@ nm_device_wifi_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_WIFI_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 WiFi",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
|
||||
NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
|
||||
|
|
@ -3675,9 +3709,6 @@ get_property (GObject *object, guint prop_id,
|
|||
else
|
||||
g_value_set_boxed (value, "/");
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, nm_device_wifi_get_ifindex (device));
|
||||
break;
|
||||
case PROP_SCANNING:
|
||||
g_value_set_boolean (value, nm_supplicant_interface_get_scanning (priv->supplicant.iface));
|
||||
break;
|
||||
|
|
@ -3697,10 +3728,6 @@ set_property (GObject *object, guint prop_id,
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_IPW_RFKILL_STATE:
|
||||
/* construct only */
|
||||
priv->ipw_rfkill_state = g_value_get_uint (value);
|
||||
|
|
@ -3743,6 +3770,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
parent_class->act_stage2_config = real_act_stage2_config;
|
||||
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
|
||||
parent_class->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout;
|
||||
parent_class->act_stage4_ip6_config_timeout = real_act_stage4_ip6_config_timeout;
|
||||
parent_class->deactivate = real_deactivate;
|
||||
parent_class->deactivate_quickly = real_deactivate_quickly;
|
||||
parent_class->can_interrupt_activation = real_can_interrupt_activation;
|
||||
|
|
@ -3788,13 +3816,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_WIFI_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCANNING,
|
||||
g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING,
|
||||
"Scanning",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_WIFI_BITRATE "bitrate"
|
||||
#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point"
|
||||
#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities"
|
||||
#define NM_DEVICE_WIFI_IFINDEX "ifindex"
|
||||
#define NM_DEVICE_WIFI_SCANNING "scanning"
|
||||
#define NM_DEVICE_WIFI_IPW_RFKILL_STATE "ipw-rfkill-state"
|
||||
|
||||
|
|
@ -84,8 +83,7 @@ GType nm_device_wifi_get_type (void);
|
|||
|
||||
NMDevice *nm_device_wifi_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
const char *driver);
|
||||
|
||||
void nm_device_wifi_get_address (NMDeviceWifi *dev,
|
||||
struct ether_addr *addr);
|
||||
|
|
@ -102,8 +100,6 @@ NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *self);
|
|||
|
||||
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
|
||||
|
||||
guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self);
|
||||
|
||||
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
457
src/nm-device.c
457
src/nm-device.c
|
|
@ -45,7 +45,7 @@
|
|||
#include "nm-named-manager.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -83,7 +83,9 @@ typedef struct {
|
|||
char * udi;
|
||||
char * path;
|
||||
char * iface; /* may change, could be renamed by user */
|
||||
int ifindex;
|
||||
char * ip_iface;
|
||||
int ip_ifindex;
|
||||
NMDeviceType type;
|
||||
char * type_desc;
|
||||
guint32 capabilities;
|
||||
|
|
@ -132,9 +134,12 @@ typedef struct {
|
|||
gulong ip6_addrconf_sigid;
|
||||
gulong ip6_config_changed_sigid;
|
||||
gboolean ip6_waiting_for_config;
|
||||
guint32 ip6_dhcp_opt;
|
||||
|
||||
char * ip6_accept_ra_path;
|
||||
guint32 ip6_accept_ra_save;
|
||||
|
||||
NMDHCPClient * dhcp6_client;
|
||||
guint32 dhcp6_mode;
|
||||
gulong dhcp6_state_sigid;
|
||||
gulong dhcp6_timeout_sigid;
|
||||
NMDHCP6Config * dhcp6_config;
|
||||
|
|
@ -175,6 +180,11 @@ static NMActStageReturn dhcp6_start (NMDevice *self,
|
|||
guint32 dhcp_opt,
|
||||
NMDeviceStateReason *reason);
|
||||
|
||||
static void addrconf6_cleanup (NMDevice *self);
|
||||
static void dhcp6_cleanup (NMDevice *self, gboolean stop);
|
||||
static void dhcp4_cleanup (NMDevice *self, gboolean stop);
|
||||
|
||||
|
||||
static void
|
||||
device_interface_init (NMDeviceInterface *device_interface_class)
|
||||
{
|
||||
|
|
@ -200,6 +210,41 @@ nm_device_init (NMDevice *self)
|
|||
priv->rfkill_type = RFKILL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
static void
|
||||
update_accept_ra_save (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
const char *ip_iface;
|
||||
char *new_path;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
ip_iface = nm_device_get_ip_iface (self);
|
||||
|
||||
new_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", ip_iface);
|
||||
g_assert (new_path);
|
||||
|
||||
if (priv->ip6_accept_ra_path) {
|
||||
/* If the IP iface is different from before, use the new value */
|
||||
if (!strcmp (new_path, priv->ip6_accept_ra_path)) {
|
||||
g_free (new_path);
|
||||
return;
|
||||
}
|
||||
g_free (priv->ip6_accept_ra_path);
|
||||
}
|
||||
|
||||
/* Grab the original value of "accept_ra" so we can restore it when NM exits */
|
||||
priv->ip6_accept_ra_path = new_path;
|
||||
if (!nm_utils_get_proc_sys_net_value (priv->ip6_accept_ra_path,
|
||||
ip_iface,
|
||||
&priv->ip6_accept_ra_save)) {
|
||||
g_free (priv->ip6_accept_ra_path);
|
||||
priv->ip6_accept_ra_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GObject*
|
||||
constructor (GType type,
|
||||
guint n_construct_params,
|
||||
|
|
@ -239,6 +284,8 @@ constructor (GType type,
|
|||
|
||||
priv->dhcp_manager = nm_dhcp_manager_get ();
|
||||
|
||||
update_accept_ra_save (dev);
|
||||
|
||||
priv->initialized = TRUE;
|
||||
return object;
|
||||
|
||||
|
|
@ -304,6 +351,13 @@ nm_device_get_iface (NMDevice *self)
|
|||
return NM_DEVICE_GET_PRIVATE (self)->iface;
|
||||
}
|
||||
|
||||
int
|
||||
nm_device_get_ifindex (NMDevice *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_ip_iface (NMDevice *self)
|
||||
|
|
@ -317,14 +371,36 @@ nm_device_get_ip_iface (NMDevice *self)
|
|||
return priv->ip_iface ? priv->ip_iface : priv->iface;
|
||||
}
|
||||
|
||||
int
|
||||
nm_device_get_ip_ifindex (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
/* If it's not set, default to iface */
|
||||
return priv->ip_iface ? priv->ip_ifindex : priv->ifindex;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_ip_iface (NMDevice *self, const char *iface)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
g_free (NM_DEVICE_GET_PRIVATE (self)->ip_iface);
|
||||
NM_DEVICE_GET_PRIVATE (self)->ip_iface = iface ? g_strdup (iface) : NULL;
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
g_free (priv->ip_iface);
|
||||
priv->ip_ifindex = 0;
|
||||
|
||||
priv->ip_iface = g_strdup (iface);
|
||||
if (priv->ip_iface) {
|
||||
priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface);
|
||||
if (!priv->ip_ifindex) {
|
||||
nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -543,9 +619,38 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family)
|
|||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_ip_config_should_fail (NMDevice *self, gboolean ip6)
|
||||
{
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
|
||||
g_return_val_if_fail (self != NULL, TRUE);
|
||||
|
||||
req = nm_device_get_act_request (self);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
/* Fail the connection if the failed IP method is required to complete */
|
||||
if (ip6) {
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6 && !nm_setting_ip6_config_get_may_fail (s_ip6))
|
||||
return TRUE;
|
||||
} else {
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (s_ip4 && !nm_setting_ip4_config_get_may_fail (s_ip4))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success,
|
||||
gpointer user_data)
|
||||
|
|
@ -558,7 +663,7 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
NMDeviceState state;
|
||||
|
||||
if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
|
||||
if (ifindex != nm_device_get_ip_ifindex (self))
|
||||
return;
|
||||
req = nm_device_get_act_request (self);
|
||||
if (!req)
|
||||
|
|
@ -576,10 +681,10 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
return;
|
||||
}
|
||||
|
||||
priv->ip6_dhcp_opt = dhcp_opts;
|
||||
priv->dhcp6_mode = dhcp_opts;
|
||||
|
||||
/* If addrconf is all that's required, we're done */
|
||||
if (dhcp_opts == IP6_DHCP_OPT_NONE) {
|
||||
if (priv->dhcp6_mode == IP6_DHCP_OPT_NONE) {
|
||||
nm_device_activate_schedule_stage4_ip6_config_get (self);
|
||||
return;
|
||||
}
|
||||
|
|
@ -596,7 +701,7 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
" as requested by IPv6 router...",
|
||||
priv->iface);
|
||||
|
||||
ret = dhcp6_start (self, connection, dhcp_opts, &reason);
|
||||
ret = dhcp6_start (self, connection, priv->dhcp6_mode, &reason);
|
||||
switch (ret) {
|
||||
case NM_ACT_STAGE_RETURN_SUCCESS:
|
||||
/* Shouldn't get this, but handle it anyway */
|
||||
|
|
@ -614,17 +719,27 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
|
||||
static void
|
||||
ip6_config_changed (NMIP6Manager *ip6_manager,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE (user_data);
|
||||
|
||||
if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
|
||||
if (ifindex != nm_device_get_ip_ifindex (self))
|
||||
return;
|
||||
if (!nm_device_get_act_request (self))
|
||||
return;
|
||||
|
||||
/* FIXME: re-run DHCPv6 here to get any new nameservers or whatever */
|
||||
|
||||
if (!success && (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED)) {
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage4_ip6_config_get (self);
|
||||
}
|
||||
|
||||
|
|
@ -635,32 +750,31 @@ ip6_method_matches (NMConnection *connection, const char *match)
|
|||
const char *method = NULL;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6)
|
||||
if (s_ip6) {
|
||||
method = nm_setting_ip6_config_get_method (s_ip6);
|
||||
g_assert (method);
|
||||
}
|
||||
|
||||
/* Treat missing IP6 setting as IGNORE */
|
||||
if (!s_ip6 && !strcmp (match, NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
|
||||
return TRUE;
|
||||
|
||||
return method && !strcmp (method, match);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
addrconf6_setup (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
const char *ip_iface;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
|
||||
priv->ip6_waiting_for_config = FALSE;
|
||||
priv->ip6_dhcp_opt = IP6_DHCP_OPT_NONE;
|
||||
|
||||
req = nm_device_get_act_request (self);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
if (!ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO))
|
||||
return;
|
||||
|
||||
if (!priv->ip6_manager) {
|
||||
priv->ip6_manager = nm_ip6_manager_get ();
|
||||
priv->ip6_addrconf_sigid = g_signal_connect (priv->ip6_manager,
|
||||
|
|
@ -673,9 +787,14 @@ addrconf6_setup (NMDevice *self)
|
|||
self);
|
||||
}
|
||||
|
||||
ip_iface = nm_device_get_ip_iface (self);
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
nm_ip6_manager_prepare_interface (priv->ip6_manager, ip_iface, s_ip6);
|
||||
nm_ip6_manager_prepare_interface (priv->ip6_manager,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
s_ip6,
|
||||
priv->ip6_accept_ra_path);
|
||||
priv->ip6_waiting_for_config = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -697,6 +816,7 @@ addrconf6_cleanup (NMDevice *self)
|
|||
priv->ip6_config_changed_sigid = 0;
|
||||
}
|
||||
|
||||
nm_ip6_manager_cancel_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self));
|
||||
g_object_unref (priv->ip6_manager);
|
||||
priv->ip6_manager = NULL;
|
||||
}
|
||||
|
|
@ -704,7 +824,6 @@ addrconf6_cleanup (NMDevice *self)
|
|||
static NMActStageReturn
|
||||
real_act_stage1_prepare (NMDevice *self, NMDeviceStateReason *reason)
|
||||
{
|
||||
addrconf6_setup (self);
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -1237,6 +1356,14 @@ dhcp_state_changed (NMDHCPClient *client,
|
|||
ipv6 = nm_dhcp_client_get_ipv6 (client);
|
||||
dev_state = nm_device_get_state (device);
|
||||
|
||||
if (ipv6) {
|
||||
nm_log_dbg (LOGD_DHCP6, "(%s): new DHCPv6 client state %d",
|
||||
nm_device_get_iface (device), dev_state);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_DHCP4, "(%s): new DHCPv4 client state %d",
|
||||
nm_device_get_iface (device), dev_state);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case DHC_BOUND4: /* lease obtained */
|
||||
case DHC_BOUND6:
|
||||
|
|
@ -1264,20 +1391,46 @@ dhcp_state_changed (NMDHCPClient *client,
|
|||
nm_device_activate_schedule_stage4_ip4_config_timeout (device);
|
||||
}
|
||||
break;
|
||||
case DHC_END: /* dhclient exited normally */
|
||||
/* In IPv6 info-only mode, the client doesn't handle leases so it
|
||||
* may exit right after getting a response from the server. That's
|
||||
* normal. In that case we just ignore the exit.
|
||||
*/
|
||||
if (ipv6 && (priv->dhcp6_mode == IP6_DHCP_OPT_OTHERCONF))
|
||||
break;
|
||||
/* Otherwise, fall through */
|
||||
case DHC_FAIL: /* all attempts to contact server timed out, sleeping */
|
||||
case DHC_ABEND: /* dhclient exited abnormally */
|
||||
case DHC_END: /* dhclient exited normally */
|
||||
if (ipv6)
|
||||
nm_dhcp6_config_reset (priv->dhcp6_config);
|
||||
else
|
||||
nm_dhcp4_config_reset (priv->dhcp4_config);
|
||||
|
||||
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
|
||||
else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
|
||||
if (ipv6)
|
||||
nm_device_activate_schedule_stage4_ip6_config_timeout (device);
|
||||
else
|
||||
nm_device_activate_schedule_stage4_ip4_config_timeout (device);
|
||||
} else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
||||
break;
|
||||
case DHC_STOP:
|
||||
case DHC_STOP6:
|
||||
case DHC_EXPIRE:
|
||||
case DHC_EXPIRE6:
|
||||
if (dev_state == NM_DEVICE_STATE_ACTIVATED) {
|
||||
if (ipv6)
|
||||
nm_dhcp6_config_reset (priv->dhcp6_config);
|
||||
else
|
||||
nm_dhcp4_config_reset (priv->dhcp4_config);
|
||||
|
||||
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1304,6 +1457,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data)
|
|||
static NMActStageReturn
|
||||
real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
|
|
@ -1333,7 +1487,6 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
guint8 *anycast = NULL;
|
||||
|
||||
/* Begin a DHCP transaction on the interface */
|
||||
|
|
@ -1389,6 +1542,10 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
*reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
} else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
/* Nothing to do... */
|
||||
priv->ip4_ready = TRUE;
|
||||
ret = NM_ACT_STAGE_RETURN_STOP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1466,7 +1623,7 @@ real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const char *ip_iface;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
|
||||
|
|
@ -1479,13 +1636,38 @@ real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
|
||||
ip_iface = nm_device_get_ip_iface (self);
|
||||
|
||||
if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
priv->ip6_waiting_for_config = TRUE;
|
||||
nm_ip6_manager_begin_addrconf (priv->ip6_manager, ip_iface);
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_DHCP))
|
||||
ret = dhcp6_start (self, connection, IP6_DHCP_OPT_MANAGED, reason);
|
||||
update_accept_ra_save (self);
|
||||
|
||||
priv->dhcp6_mode = IP6_DHCP_OPT_NONE;
|
||||
|
||||
if ( ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|
||||
|| ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
|
||||
if (!addrconf6_setup (self)) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
goto out;
|
||||
}
|
||||
nm_ip6_manager_begin_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self));
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
|
||||
/* Router advertisements shouldn't be used in pure DHCP mode */
|
||||
if (priv->ip6_accept_ra_path)
|
||||
nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n");
|
||||
|
||||
priv->dhcp6_mode = IP6_DHCP_OPT_MANAGED;
|
||||
ret = dhcp6_start (self, connection, priv->dhcp6_mode, reason);
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
||||
priv->ip6_ready = TRUE;
|
||||
ret = NM_ACT_STAGE_RETURN_STOP;
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
/* Router advertisements shouldn't be used in manual mode */
|
||||
if (priv->ip6_accept_ra_path)
|
||||
nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n");
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/* Other methods (shared) aren't implemented yet */
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1517,6 +1699,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
|||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
||||
/* Nothing to do */
|
||||
} else
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
||||
|
||||
|
|
@ -1526,6 +1710,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
|||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
||||
/* Nothing to do */
|
||||
} else
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
||||
|
||||
|
|
@ -1674,7 +1860,8 @@ real_act_stage4_get_ip4_config (NMDevice *self,
|
|||
*config = nm_device_new_ip4_shared_config (self, reason);
|
||||
if (*config)
|
||||
priv->dnsmasq_manager = nm_dnsmasq_manager_new (ip_iface);
|
||||
}
|
||||
} else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
if (!*config) {
|
||||
|
|
@ -1712,8 +1899,7 @@ nm_device_activate_stage4_ip4_config_get (gpointer user_data)
|
|||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, &ip4_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE))
|
||||
{
|
||||
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1767,9 +1953,12 @@ real_act_stage4_ip4_config_timeout (NMDevice *self,
|
|||
/* Notify of invalid DHCP4 config object */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP4_CONFIG);
|
||||
|
||||
/* DHCP failed; connection must fail */
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
if (nm_device_ip_config_should_fail (self, FALSE)) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1797,17 +1986,18 @@ nm_device_activate_stage4_ip4_config_timeout (gpointer user_data)
|
|||
iface);
|
||||
|
||||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip4_config_timeout (self, &ip4_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
} else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
|
||||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
||||
g_assert (ip4_config);
|
||||
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP4_CONFIG, ip4_config);
|
||||
if (ip4_config) {
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP4_CONFIG, ip4_config);
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET);
|
||||
|
||||
|
|
@ -1842,13 +2032,48 @@ nm_device_activate_schedule_stage4_ip4_config_timeout (NMDevice *self)
|
|||
nm_device_get_iface (self));
|
||||
}
|
||||
|
||||
static void
|
||||
merge_dhcp_config_to_master (NMIP6Config *dst, NMIP6Config *src)
|
||||
{
|
||||
guint32 i;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
|
||||
/* addresses */
|
||||
for (i = 0; i < nm_ip6_config_get_num_addresses (src); i++)
|
||||
nm_ip6_config_add_address (dst, nm_ip6_config_get_address (src, i));
|
||||
|
||||
/* ptp address; only replace if src doesn't have one */
|
||||
if (!nm_ip6_config_get_ptp_address (dst))
|
||||
nm_ip6_config_set_ptp_address (dst, nm_ip6_config_get_ptp_address (src));
|
||||
|
||||
/* nameservers */
|
||||
for (i = 0; i < nm_ip6_config_get_num_nameservers (src); i++)
|
||||
nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i));
|
||||
|
||||
/* routes */
|
||||
for (i = 0; i < nm_ip6_config_get_num_routes (src); i++)
|
||||
nm_ip6_config_add_route (dst, nm_ip6_config_get_route (src, i));
|
||||
|
||||
/* domains */
|
||||
for (i = 0; i < nm_ip6_config_get_num_domains (src); i++)
|
||||
nm_ip6_config_add_domain (dst, nm_ip6_config_get_domain (src, i));
|
||||
|
||||
/* dns searches */
|
||||
for (i = 0; i < nm_ip6_config_get_num_searches (src); i++)
|
||||
nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i));
|
||||
|
||||
if (!nm_ip6_config_get_mss (dst))
|
||||
nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src));
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_get_ip6_config (NMDevice *self,
|
||||
NMIP6Config **config,
|
||||
NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMConnection *connection;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
const char *ip_iface;
|
||||
|
|
@ -1863,15 +2088,17 @@ real_act_stage4_get_ip6_config (NMDevice *self,
|
|||
connection = nm_act_request_get_connection (nm_device_get_act_request (self));
|
||||
g_assert (connection);
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
|
||||
if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
*config = nm_ip6_manager_get_ip6_config (priv->ip6_manager, ip_iface);
|
||||
if (*config) {
|
||||
/* Merge user-defined overrides into the IP6Config to be applied */
|
||||
nm_utils_merge_ip6_config (*config, s_ip6);
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
} else {
|
||||
if ( ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|
||||
|| ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
|
||||
*config = nm_ip6_manager_get_ip6_config (priv->ip6_manager,
|
||||
nm_device_get_ip_ifindex (self));
|
||||
if (!*config) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
goto out;
|
||||
}
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
*config = nm_ip6_config_new ();
|
||||
if (!*config) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1880,29 +2107,49 @@ real_act_stage4_get_ip6_config (NMDevice *self,
|
|||
|
||||
/* Autoconf might have triggered DHCPv6 too */
|
||||
if (priv->dhcp6_client) {
|
||||
*config = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE);
|
||||
if (*config) {
|
||||
/* Merge user-defined overrides into the IP4Config to be applied */
|
||||
nm_utils_merge_ip6_config (*config, s_ip6);
|
||||
NMIP6Config *dhcp;
|
||||
|
||||
nm_dhcp6_config_reset (priv->dhcp6_config);
|
||||
nm_dhcp_client_foreach_option (priv->dhcp6_client,
|
||||
dhcp6_add_option_cb,
|
||||
priv->dhcp6_config);
|
||||
|
||||
/* Notify of new DHCP4 config */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG);
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
} else {
|
||||
dhcp = nm_dhcp_client_get_ip6_config (priv->dhcp6_client, FALSE);
|
||||
if (!dhcp) {
|
||||
*reason = NM_DEVICE_STATE_REASON_DHCP_ERROR;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
*config = NULL;
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
|
||||
/* For "managed" and DHCP-only setups, we use only the DHCP-supplied
|
||||
* IPv6 config. But when autoconf is enabled, we have to merge the
|
||||
* autoconf config and the DHCP-supplied config, then merge the
|
||||
* user's overrides from the connection to get the final configuration
|
||||
* that gets applied to the device.
|
||||
*/
|
||||
if (*config) {
|
||||
/* Merge autoconf and DHCP configs */
|
||||
merge_dhcp_config_to_master (*config, dhcp);
|
||||
g_object_unref (dhcp);
|
||||
dhcp = NULL;
|
||||
} else {
|
||||
*config = dhcp;
|
||||
}
|
||||
|
||||
/* Copy the new DHCPv6 configuration into the DHCP config object that's
|
||||
* exported over D-Bus to clients.
|
||||
*/
|
||||
nm_dhcp6_config_reset (priv->dhcp6_config);
|
||||
nm_dhcp_client_foreach_option (priv->dhcp6_client,
|
||||
dhcp6_add_option_cb,
|
||||
priv->dhcp6_config);
|
||||
|
||||
/* Notify of new DHCP6 config */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG);
|
||||
}
|
||||
|
||||
/* Merge user-defined overrides into the IP6Config to be applied */
|
||||
if (*config) {
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
nm_utils_merge_ip6_config (*config, s_ip6);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return *config ? NM_ACT_STAGE_RETURN_SUCCESS : NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1983,11 +2230,15 @@ real_act_stage4_ip6_config_timeout (NMDevice *self,
|
|||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
/* Notify of invalid DHCP6 config object */
|
||||
/* Notify of invalid DHCP4 config object */
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG);
|
||||
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
if (nm_device_ip_config_should_fail (self, TRUE)) {
|
||||
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2015,17 +2266,18 @@ nm_device_activate_stage4_ip6_config_timeout (gpointer user_data)
|
|||
iface);
|
||||
|
||||
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip6_config_timeout (self, &ip6_config, &reason);
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
|
||||
if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
||||
/* FIXME g_assert (ip6_config); */
|
||||
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP6_CONFIG, ip6_config);
|
||||
if (ip6_config) {
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP6_CONFIG, ip6_config);
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET6);
|
||||
|
||||
|
|
@ -2230,6 +2482,16 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
|
||||
assumed = nm_act_request_get_assumed (priv->act_request);
|
||||
|
||||
if (!ip6_config && !ip4_config) {
|
||||
nm_log_info (LOGD_DEVICE,
|
||||
"Activation (%s) Stage 5 of 5 (IP Configure Commit) failed (no IP configuration found)",
|
||||
iface);
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ip4_config && !nm_device_set_ip4_config (self, ip4_config, assumed, &reason)) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
|
|
@ -2239,6 +2501,8 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
nm_log_info (LOGD_DEVICE | LOGD_IP6,
|
||||
"Activation (%s) Stage 5 of 5 (IP Configure Commit) IPv6 failed",
|
||||
iface);
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (nm_device_get_act_request (self));
|
||||
|
|
@ -2248,7 +2512,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
if (s_ip4)
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (s_ip4 && !strcmp (method, "shared")) {
|
||||
if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
if (!start_sharing (self)) {
|
||||
nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IP Configure Commit) start sharing failed.", iface);
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
|
||||
|
|
@ -2394,6 +2658,8 @@ dhcp6_cleanup (NMDevice *self, gboolean stop)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
priv->dhcp6_mode = IP6_DHCP_OPT_NONE;
|
||||
|
||||
if (priv->dhcp6_config) {
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_DHCP6_CONFIG);
|
||||
g_object_unref (priv->dhcp6_config);
|
||||
|
|
@ -2467,6 +2733,10 @@ nm_device_deactivate_quickly (NMDevice *self)
|
|||
dnsmasq_cleanup (self);
|
||||
aipd_cleanup (self);
|
||||
|
||||
/* Turn off router advertisements until they are needed */
|
||||
if (priv->ip6_accept_ra_path)
|
||||
nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n");
|
||||
|
||||
/* Call device type-specific deactivation */
|
||||
if (NM_DEVICE_GET_CLASS (self)->deactivate_quickly)
|
||||
NM_DEVICE_GET_CLASS (self)->deactivate_quickly (self);
|
||||
|
|
@ -2497,7 +2767,7 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
|
|||
nm_device_deactivate_quickly (self);
|
||||
|
||||
/* Take out any entries in the routing table and any IP address the device had. */
|
||||
nm_system_device_flush_routes (self);
|
||||
nm_system_device_flush_routes (self, nm_device_get_ip6_config (self) ? AF_UNSPEC : AF_INET);
|
||||
nm_system_device_flush_addresses (self);
|
||||
nm_device_update_ip4_address (self);
|
||||
|
||||
|
|
@ -3038,6 +3308,13 @@ dispose (GObject *object)
|
|||
addrconf6_cleanup (self);
|
||||
dnsmasq_cleanup (self);
|
||||
|
||||
/* reset the saved RA value */
|
||||
if (priv->ip6_accept_ra_path) {
|
||||
nm_utils_do_sysctl (priv->ip6_accept_ra_path,
|
||||
priv->ip6_accept_ra_save ? "1\n" : "0\n");
|
||||
}
|
||||
g_free (priv->ip6_accept_ra_path);
|
||||
|
||||
/* Take the device itself down and clear its IPv4 configuration */
|
||||
if (priv->managed && take_down) {
|
||||
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
|
||||
|
|
@ -3088,7 +3365,14 @@ set_property (GObject *object, guint prop_id,
|
|||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_IFACE:
|
||||
g_free (priv->iface);
|
||||
priv->ifindex = 0;
|
||||
priv->iface = g_value_dup_string (value);
|
||||
if (priv->iface) {
|
||||
priv->ifindex = nm_netlink_iface_to_index (priv->iface);
|
||||
if (priv->ifindex < 0) {
|
||||
nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", priv->iface);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_DRIVER:
|
||||
priv->driver = g_strdup (g_value_get_string (value));
|
||||
|
|
@ -3136,6 +3420,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case NM_DEVICE_INTERFACE_PROP_IFACE:
|
||||
g_value_set_string (value, priv->iface);
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_IFINDEX:
|
||||
g_value_set_int (value, priv->ifindex);
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_DRIVER:
|
||||
g_value_set_string (value, priv->driver);
|
||||
break;
|
||||
|
|
@ -3234,6 +3521,10 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
NM_DEVICE_INTERFACE_PROP_IFACE,
|
||||
NM_DEVICE_INTERFACE_IFACE);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
NM_DEVICE_INTERFACE_PROP_IFINDEX,
|
||||
NM_DEVICE_INTERFACE_IFINDEX);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
NM_DEVICE_INTERFACE_PROP_DRIVER,
|
||||
NM_DEVICE_INTERFACE_DRIVER);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ typedef enum NMActStageReturn
|
|||
{
|
||||
NM_ACT_STAGE_RETURN_FAILURE = 0,
|
||||
NM_ACT_STAGE_RETURN_SUCCESS,
|
||||
NM_ACT_STAGE_RETURN_POSTPONE
|
||||
NM_ACT_STAGE_RETURN_POSTPONE,
|
||||
NM_ACT_STAGE_RETURN_STOP /* This activation chain is done */
|
||||
} NMActStageReturn;
|
||||
|
||||
|
||||
|
|
@ -128,7 +129,9 @@ void nm_device_set_path (NMDevice *dev, const char *path);
|
|||
|
||||
const char * nm_device_get_udi (NMDevice *dev);
|
||||
const char * nm_device_get_iface (NMDevice *dev);
|
||||
int nm_device_get_ifindex (NMDevice *dev);
|
||||
const char * nm_device_get_ip_iface (NMDevice *dev);
|
||||
int nm_device_get_ip_ifindex(NMDevice *dev);
|
||||
const char * nm_device_get_driver (NMDevice *dev);
|
||||
const char * nm_device_get_type_desc (NMDevice *dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2005 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2006 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ const struct in6_addr *nm_ip6_config_get_ptp_address (NMIP6Config *config)
|
|||
return &NM_IP6_CONFIG_GET_PRIVATE (config)->ptp_address;
|
||||
}
|
||||
|
||||
void nm_ip6_config_set_ptp_address (NMIP6Config *config, struct in6_addr *ptp_addr)
|
||||
void nm_ip6_config_set_ptp_address (NMIP6Config *config, const struct in6_addr *ptp_addr)
|
||||
{
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (config));
|
||||
|
||||
|
|
@ -197,15 +197,14 @@ void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *n
|
|||
int i;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (config));
|
||||
g_return_if_fail (nameserver > 0);
|
||||
g_return_if_fail (nameserver != NULL);
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
/* No dupes */
|
||||
nameservers = (struct in6_addr *)priv->nameservers->data;
|
||||
for (i = 0; i < priv->nameservers->len; i++) {
|
||||
g_return_if_fail (memcmp (nameserver, &nameservers[i], sizeof (struct in6_addr)) != 0);
|
||||
}
|
||||
for (i = 0; i < priv->nameservers->len; i++)
|
||||
g_return_if_fail (IN6_ARE_ADDR_EQUAL (nameserver, &nameservers[i]) == FALSE);
|
||||
|
||||
g_array_append_val (priv->nameservers, *nameserver);
|
||||
}
|
||||
|
|
@ -572,7 +571,7 @@ addr_array_compare (GArray *a, GArray *b)
|
|||
addrs_b = (struct in6_addr *)b->data;
|
||||
for (i = 0; i < a->len; i++) {
|
||||
for (j = 0, found = FALSE; j < b->len; j++) {
|
||||
if (memcmp (&addrs_a[i], &addrs_b[j], sizeof (struct in6_addr)) == 0) {
|
||||
if (IN6_ARE_ADDR_EQUAL (&addrs_a[i], &addrs_b[j])) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -692,34 +691,33 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
|
|||
object_class->finalize = finalize;
|
||||
|
||||
/* properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"IP6 addresses",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_NAMESERVERS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS,
|
||||
"Nameservers",
|
||||
"DNS list",
|
||||
DBUS_TYPE_G_UINT_ARRAY,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DOMAINS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS,
|
||||
"Domains",
|
||||
"Domains",
|
||||
DBUS_TYPE_G_ARRAY_OF_STRING,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ROUTES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
|
||||
"Routes",
|
||||
"Routes",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property (object_class, PROP_ADDRESSES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"IP6 addresses",
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_NAMESERVERS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS,
|
||||
"Nameservers",
|
||||
"DNS list",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DOMAINS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS,
|
||||
"Domains",
|
||||
"Domains",
|
||||
DBUS_TYPE_G_ARRAY_OF_STRING,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ROUTES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
|
||||
"Routes",
|
||||
"Routes",
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
|
||||
&dbus_glib_nm_ip6_config_object_info);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ NMIP6Address *nm_ip6_config_get_address (NMIP6Config *config, guint32 i)
|
|||
guint32 nm_ip6_config_get_num_addresses (NMIP6Config *config);
|
||||
|
||||
const struct in6_addr *nm_ip6_config_get_ptp_address (NMIP6Config *config);
|
||||
void nm_ip6_config_set_ptp_address (NMIP6Config *config, struct in6_addr *ptp_addr);
|
||||
void nm_ip6_config_set_ptp_address (NMIP6Config *config, const struct in6_addr *ptp_addr);
|
||||
|
||||
void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *nameserver);
|
||||
const struct in6_addr *nm_ip6_config_get_nameserver (NMIP6Config *config, guint i);
|
||||
|
|
|
|||
|
|
@ -1523,7 +1523,8 @@ add_device (NMManager *self, NMDevice *device)
|
|||
driver = nm_device_get_driver (device);
|
||||
if (!driver)
|
||||
driver = "unknown";
|
||||
nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s')", iface, type_desc, driver);
|
||||
nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s' ifindex: %d)",
|
||||
iface, type_desc, driver, nm_device_get_ifindex (device));
|
||||
|
||||
path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++);
|
||||
nm_device_set_path (device, path);
|
||||
|
|
@ -1794,20 +1795,11 @@ find_device_by_ifindex (NMManager *self, guint32 ifindex)
|
|||
GSList *iter;
|
||||
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
gint candidate_idx = 0;
|
||||
NMDevice *candidate = NM_DEVICE (iter->data);
|
||||
|
||||
if (NM_IS_DEVICE_ETHERNET (device))
|
||||
candidate_idx = nm_device_ethernet_get_ifindex (NM_DEVICE_ETHERNET (device));
|
||||
else if (NM_IS_DEVICE_WIFI (device))
|
||||
candidate_idx = nm_device_wifi_get_ifindex (NM_DEVICE_WIFI (device));
|
||||
else if (NM_IS_DEVICE_OLPC_MESH (device))
|
||||
candidate_idx = nm_device_olpc_mesh_get_ifindex (NM_DEVICE_OLPC_MESH (device));
|
||||
|
||||
if (candidate_idx == ifindex)
|
||||
return device;
|
||||
if (ifindex == nm_device_get_ifindex (candidate))
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2782,7 +2774,12 @@ impl_manager_set_logging (NMManager *manager,
|
|||
GError **error)
|
||||
{
|
||||
if (nm_logging_setup (level, domains, error)) {
|
||||
nm_log_info (LOGD_CORE, "logging: level '%s' domains '%s'", level, domains);
|
||||
char *new_domains = nm_logging_domains_to_string ();
|
||||
|
||||
nm_log_info (LOGD_CORE, "logging: level '%s' domains '%s'",
|
||||
nm_logging_level_to_string (),
|
||||
new_domains);
|
||||
g_free (new_domains);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2005 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*/
|
||||
|
|
@ -25,16 +25,15 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/link.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_NETLINK_MONITOR (nm_netlink_monitor_get_type ())
|
||||
#define NM_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitor))
|
||||
#define NM_TYPE_NETLINK_MONITOR (nm_netlink_monitor_get_type ())
|
||||
#define NM_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitor))
|
||||
#define NM_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitorClass))
|
||||
#define NM_IS_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_IS_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_IS_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_NETLINK_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitorClass))
|
||||
#define NM_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_quark ())
|
||||
|
||||
typedef enum {
|
||||
NM_NETLINK_MONITOR_ERROR_GENERIC = 0,
|
||||
|
|
@ -56,29 +55,45 @@ typedef struct {
|
|||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*carrier_on) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*carrier_off) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*error) (NMNetlinkMonitor *monitor, GError *error);
|
||||
void (*notification) (NMNetlinkMonitor *monitor, struct nl_msg *msg);
|
||||
void (*carrier_on) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*carrier_off) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*error) (NMNetlinkMonitor *monitor, GError *error);
|
||||
} NMNetlinkMonitorClass;
|
||||
|
||||
|
||||
GType nm_netlink_monitor_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_monitor_error_quark (void) G_GNUC_CONST;
|
||||
#define NM_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_quark ())
|
||||
GType nm_netlink_monitor_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_monitor_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
NMNetlinkMonitor *nm_netlink_monitor_get (void);
|
||||
|
||||
gboolean nm_netlink_monitor_open_connection (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
gboolean nm_netlink_monitor_open_connection (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
void nm_netlink_monitor_close_connection (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_attach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_detach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_attach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_detach (NMNetlinkMonitor *monitor);
|
||||
|
||||
gboolean nm_netlink_monitor_subscribe (NMNetlinkMonitor *monitor,
|
||||
int group,
|
||||
GError **error);
|
||||
void nm_netlink_monitor_unsubscribe (NMNetlinkMonitor *monitor,
|
||||
int group);
|
||||
|
||||
gboolean nm_netlink_monitor_request_ip6_info (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
GError **error);
|
||||
gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor,
|
||||
guint32 ifindex,
|
||||
guint32 *ifflags,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
/* Generic utility functions */
|
||||
int nm_netlink_iface_to_index (const char *iface);
|
||||
char * nm_netlink_index_to_iface (int idx);
|
||||
struct rtnl_link *nm_netlink_index_to_rtnl_link (int idx);
|
||||
struct nl_handle *nm_netlink_get_default_handle (void);
|
||||
|
||||
#endif /* NM_NETLINK_MONITOR_H */
|
||||
|
|
|
|||
149
src/nm-netlink.c
149
src/nm-netlink.c
|
|
@ -1,149 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <netlink/object-api.h>
|
||||
|
||||
static struct nl_cache * link_cache = NULL;
|
||||
static struct nl_handle * def_nl_handle = NULL;
|
||||
|
||||
|
||||
static struct nl_cache *
|
||||
get_link_cache (void)
|
||||
{
|
||||
struct nl_handle * nlh;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
if (G_UNLIKELY (!nlh)) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink handle.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!link_cache))
|
||||
link_cache = rtnl_link_alloc_cache (nlh);
|
||||
|
||||
if (G_UNLIKELY (!link_cache)) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink link cache: %s", nl_geterror ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nl_cache_update (nlh, link_cache);
|
||||
return link_cache;
|
||||
}
|
||||
|
||||
|
||||
struct nl_handle *
|
||||
nm_netlink_get_default_handle (void)
|
||||
{
|
||||
struct nl_cb *cb;
|
||||
#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
|
||||
struct nl_cache *addr_cache;
|
||||
#endif
|
||||
|
||||
if (def_nl_handle)
|
||||
return def_nl_handle;
|
||||
|
||||
cb = nl_cb_alloc(NL_CB_VERBOSE);
|
||||
def_nl_handle = nl_handle_alloc_cb (cb);
|
||||
if (!def_nl_handle) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink handle.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nl_connect (def_nl_handle, NETLINK_ROUTE) < 0) {
|
||||
nm_log_err (LOGD_HW, "couldn't connect to netlink: %s", nl_geterror ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
|
||||
/* Work around apparent libnl bug; rtnl_addr requires that all
|
||||
* addresses have the "peer" attribute set in order to be compared
|
||||
* for equality, but this attribute is not normally set. As a
|
||||
* result, most addresses will not compare as equal even to
|
||||
* themselves, busting caching.
|
||||
*/
|
||||
addr_cache = rtnl_addr_alloc_cache (def_nl_handle);
|
||||
nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80;
|
||||
nl_cache_free (addr_cache);
|
||||
#endif
|
||||
|
||||
return def_nl_handle;
|
||||
}
|
||||
|
||||
int
|
||||
nm_netlink_iface_to_index (const char *iface)
|
||||
{
|
||||
struct nl_cache * cache;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, -1);
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return RTNL_LINK_NOT_FOUND;
|
||||
|
||||
return rtnl_link_name2i (cache, iface);
|
||||
}
|
||||
|
||||
|
||||
#define MAX_IFACE_LEN 33
|
||||
char *
|
||||
nm_netlink_index_to_iface (int idx)
|
||||
{
|
||||
struct nl_cache * cache;
|
||||
char * buf = NULL;
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
buf = g_malloc0 (MAX_IFACE_LEN);
|
||||
if (buf == NULL) {
|
||||
nm_log_warn (LOGD_HW, "Not enough memory to allocate interface name buffer.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rtnl_link_i2name (cache, idx, buf, MAX_IFACE_LEN - 1) == NULL) {
|
||||
g_free (buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct rtnl_link *
|
||||
nm_netlink_index_to_rtnl_link (int idx)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
return rtnl_link_get (cache, idx);
|
||||
}
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_NETLINK_H
|
||||
#define NM_NETLINK_H
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <netlink/route/addr.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/route/link.h>
|
||||
|
||||
int nm_netlink_iface_to_index (const char *iface);
|
||||
char * nm_netlink_index_to_iface (int idx);
|
||||
struct rtnl_link * nm_netlink_index_to_rtnl_link (int idx);
|
||||
|
||||
struct nl_handle * nm_netlink_get_default_handle (void);
|
||||
|
||||
#endif /* NM_NETLINK_H */
|
||||
205
src/nm-policy-hostname.c
Normal file
205
src/nm-policy-hostname.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2004 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-policy-hostname.h"
|
||||
#include "nm-policy-hosts.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
struct HostnameThread {
|
||||
GThread *thread;
|
||||
|
||||
GMutex *lock;
|
||||
gboolean dead;
|
||||
int ret;
|
||||
|
||||
guint32 ip4_addr;
|
||||
char hostname[NI_MAXHOST + 1];
|
||||
|
||||
HostnameThreadCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
hostname_thread_run_cb (gpointer user_data)
|
||||
{
|
||||
HostnameThread *ht = (HostnameThread *) user_data;
|
||||
const char *hostname = NULL;
|
||||
|
||||
if (strlen (ht->hostname))
|
||||
hostname = ht->hostname;
|
||||
|
||||
(*ht->callback) (ht, ht->ret, hostname, ht->user_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
hostname_thread_worker (gpointer data)
|
||||
{
|
||||
HostnameThread *ht = (HostnameThread *) data;
|
||||
struct sockaddr_in addr;
|
||||
int i;
|
||||
|
||||
g_mutex_lock (ht->lock);
|
||||
if (ht->dead) {
|
||||
g_mutex_unlock (ht->lock);
|
||||
return (gpointer) NULL;
|
||||
}
|
||||
g_mutex_unlock (ht->lock);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = ht->ip4_addr;
|
||||
|
||||
ht->ret = getnameinfo ((struct sockaddr *) &addr, sizeof (struct sockaddr_in),
|
||||
ht->hostname, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (ht->ret == 0) {
|
||||
for (i = 0; i < strlen (ht->hostname); i++)
|
||||
ht->hostname[i] = tolower (ht->hostname[i]);
|
||||
}
|
||||
|
||||
/* Don't track the idle handler ID because by the time the g_idle_add()
|
||||
* returns the ID, the handler may already have run and freed the
|
||||
* HostnameThread.
|
||||
*/
|
||||
g_idle_add (hostname_thread_run_cb, ht);
|
||||
return (gpointer) TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
hostname_thread_free (HostnameThread *ht)
|
||||
{
|
||||
g_return_if_fail (ht != NULL);
|
||||
|
||||
g_mutex_free (ht->lock);
|
||||
memset (ht, 0, sizeof (HostnameThread));
|
||||
g_free (ht);
|
||||
}
|
||||
|
||||
HostnameThread *
|
||||
hostname_thread_new (guint32 ip4_addr, HostnameThreadCallback callback, gpointer user_data)
|
||||
{
|
||||
HostnameThread *ht;
|
||||
|
||||
ht = g_malloc0 (sizeof (HostnameThread));
|
||||
g_assert (ht);
|
||||
|
||||
ht->lock = g_mutex_new ();
|
||||
ht->callback = callback;
|
||||
ht->user_data = user_data;
|
||||
ht->ip4_addr = ip4_addr;
|
||||
|
||||
ht->thread = g_thread_create (hostname_thread_worker, ht, FALSE, NULL);
|
||||
if (!ht->thread) {
|
||||
hostname_thread_free (ht);
|
||||
ht = NULL;
|
||||
}
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
void
|
||||
hostname_thread_kill (HostnameThread *ht)
|
||||
{
|
||||
g_return_if_fail (ht != NULL);
|
||||
|
||||
g_mutex_lock (ht->lock);
|
||||
ht->dead = TRUE;
|
||||
g_mutex_unlock (ht->lock);
|
||||
}
|
||||
|
||||
gboolean
|
||||
hostname_thread_is_dead (HostnameThread *ht)
|
||||
{
|
||||
g_return_val_if_fail (ht != NULL, TRUE);
|
||||
|
||||
return ht->dead;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define FALLBACK_HOSTNAME "localhost.localdomain"
|
||||
|
||||
gboolean
|
||||
nm_policy_set_system_hostname (const char *new_hostname, const char *msg)
|
||||
{
|
||||
char old_hostname[HOST_NAME_MAX + 1];
|
||||
int ret = 0;
|
||||
const char *name;
|
||||
gboolean set_hostname = TRUE, changed = FALSE;
|
||||
|
||||
if (new_hostname)
|
||||
g_warn_if_fail (strlen (new_hostname));
|
||||
|
||||
name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME;
|
||||
|
||||
old_hostname[HOST_NAME_MAX] = '\0';
|
||||
errno = 0;
|
||||
ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||
errno, strerror (errno));
|
||||
} else {
|
||||
/* Don't set the hostname if it isn't actually changing */
|
||||
if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||
|| (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME)))
|
||||
set_hostname = FALSE;
|
||||
}
|
||||
|
||||
if (set_hostname) {
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||
ret = sethostname (name, strlen (name));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||
name, errno, strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* But even if the hostname isn't changing, always try updating /etc/hosts
|
||||
* just in case the hostname changed while NM wasn't running; we need to
|
||||
* make sure that /etc/hosts has valid mappings for '127.0.0.1' and the
|
||||
* current system hostname. If those exist,
|
||||
* nm_policy_hosts_update_etc_hosts() will just return and won't touch
|
||||
* /etc/hosts at all.
|
||||
*/
|
||||
if (!nm_policy_hosts_update_etc_hosts (name, FALLBACK_HOSTNAME, &changed)) {
|
||||
/* error updating /etc/hosts; fallback to localhost.localdomain */
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '" FALLBACK_HOSTNAME "' (error updating /etc/hosts)");
|
||||
ret = sethostname (FALLBACK_HOSTNAME, strlen (FALLBACK_HOSTNAME));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the fallback system hostname (%s): (%d) %s",
|
||||
FALLBACK_HOSTNAME, errno, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
47
src/nm-policy-hostname.h
Normal file
47
src/nm-policy-hostname.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2004 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_POLICY_HOSTNAME_H
|
||||
#define NM_POLICY_HOSTNAME_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
gboolean nm_policy_set_system_hostname (const char *new_hostname, const char *msg);
|
||||
|
||||
|
||||
typedef struct HostnameThread HostnameThread;
|
||||
|
||||
typedef void (*HostnameThreadCallback) (HostnameThread *ht,
|
||||
int error,
|
||||
const char *hostname,
|
||||
gpointer user_data);
|
||||
|
||||
HostnameThread * hostname_thread_new (guint32 ip4_addr,
|
||||
HostnameThreadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void hostname_thread_free (HostnameThread *ht);
|
||||
|
||||
gboolean hostname_thread_is_dead (HostnameThread *ht);
|
||||
|
||||
void hostname_thread_kill (HostnameThread *ht);
|
||||
|
||||
#endif /* NM_POLICY_HOSTNAME_H */
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "nm-policy-hosts.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
gboolean
|
||||
nm_policy_hosts_find_token (const char *line, const char *token)
|
||||
|
|
@ -171,3 +172,64 @@ nm_policy_get_etc_hosts (const char **lines,
|
|||
return contents;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_policy_hosts_update_etc_hosts (const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
gboolean *out_changed)
|
||||
{
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
GError *error = NULL;
|
||||
GString *new_contents = NULL;
|
||||
gsize contents_len = 0;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (hostname != NULL, FALSE);
|
||||
g_return_val_if_fail (out_changed != NULL, FALSE);
|
||||
|
||||
if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the new /etc/hosts contents */
|
||||
lines = g_strsplit_set (contents, "\n\r", 0);
|
||||
new_contents = nm_policy_get_etc_hosts ((const char **) lines,
|
||||
contents_len,
|
||||
hostname,
|
||||
fallback_hostname,
|
||||
&error);
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
|
||||
if (new_contents) {
|
||||
nm_log_info (LOGD_DNS, "Updating /etc/hosts with new system hostname");
|
||||
|
||||
g_clear_error (&error);
|
||||
/* And actually update /etc/hosts */
|
||||
if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
success = TRUE;
|
||||
*out_changed = TRUE;
|
||||
}
|
||||
|
||||
g_string_free (new_contents, TRUE);
|
||||
} else if (!error) {
|
||||
/* No change required */
|
||||
success = TRUE;
|
||||
} else {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error->code, error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,18 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
gboolean nm_policy_hosts_update_etc_hosts (const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
gboolean *out_changed);
|
||||
|
||||
/* Only for testcases; don't use outside of nm-policy-hosts.c */
|
||||
gboolean nm_policy_hosts_find_token (const char *line, const char *token);
|
||||
|
||||
GString *nm_policy_get_etc_hosts (const char **lines,
|
||||
gsize existing_len,
|
||||
const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
GError **error);
|
||||
|
||||
/* Only for testcases; don't use outside of nm-policy-hosts.c */
|
||||
gboolean nm_policy_hosts_find_token (const char *line, const char *token);
|
||||
|
||||
#endif /* NM_POLICY_HOSTS_H */
|
||||
|
||||
|
|
|
|||
510
src/nm-policy.c
510
src/nm-policy.c
|
|
@ -42,24 +42,7 @@
|
|||
#include "nm-named-manager.h"
|
||||
#include "nm-vpn-manager.h"
|
||||
#include "nm-policy-hosts.h"
|
||||
|
||||
typedef struct LookupThread LookupThread;
|
||||
|
||||
typedef void (*LookupCallback) (LookupThread *thread, gpointer user_data);
|
||||
|
||||
struct LookupThread {
|
||||
GThread *thread;
|
||||
|
||||
GMutex *lock;
|
||||
gboolean die;
|
||||
int ret;
|
||||
|
||||
guint32 ip4_addr;
|
||||
char hostname[NI_MAXHOST + 1];
|
||||
|
||||
LookupCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
#include "nm-policy-hostname.h"
|
||||
|
||||
struct NMPolicy {
|
||||
NMManager *manager;
|
||||
|
|
@ -72,99 +55,14 @@ struct NMPolicy {
|
|||
gulong vpn_activated_id;
|
||||
gulong vpn_deactivated_id;
|
||||
|
||||
NMDevice *default_device;
|
||||
NMDevice *default_device4;
|
||||
NMDevice *default_device6;
|
||||
|
||||
LookupThread *lookup;
|
||||
HostnameThread *lookup;
|
||||
|
||||
char *orig_hostname; /* hostname at NM start time */
|
||||
};
|
||||
|
||||
static gboolean
|
||||
lookup_thread_run_cb (gpointer user_data)
|
||||
{
|
||||
LookupThread *thread = (LookupThread *) user_data;
|
||||
|
||||
(*thread->callback) (thread, thread->user_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
lookup_thread_worker (gpointer data)
|
||||
{
|
||||
LookupThread *thread = (LookupThread *) data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
g_mutex_lock (thread->lock);
|
||||
if (thread->die) {
|
||||
g_mutex_unlock (thread->lock);
|
||||
return (gpointer) NULL;
|
||||
}
|
||||
g_mutex_unlock (thread->lock);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = thread->ip4_addr;
|
||||
|
||||
thread->ret = getnameinfo ((struct sockaddr *) &addr, sizeof (struct sockaddr_in),
|
||||
thread->hostname, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (thread->ret == 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < strlen (thread->hostname); i++)
|
||||
thread->hostname[i] = tolower (thread->hostname[i]);
|
||||
}
|
||||
|
||||
/* Don't track the idle handler ID because by the time the g_idle_add()
|
||||
* returns the ID, the handler may already have run and freed the
|
||||
* LookupThread.
|
||||
*/
|
||||
g_idle_add (lookup_thread_run_cb, thread);
|
||||
return (gpointer) TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_thread_free (LookupThread *thread)
|
||||
{
|
||||
g_return_if_fail (thread != NULL);
|
||||
|
||||
g_mutex_free (thread->lock);
|
||||
memset (thread, 0, sizeof (LookupThread));
|
||||
g_free (thread);
|
||||
}
|
||||
|
||||
static LookupThread *
|
||||
lookup_thread_new (guint32 ip4_addr, LookupCallback callback, gpointer user_data)
|
||||
{
|
||||
LookupThread *thread;
|
||||
|
||||
thread = g_malloc0 (sizeof (LookupThread));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
thread->lock = g_mutex_new ();
|
||||
thread->callback = callback;
|
||||
thread->user_data = user_data;
|
||||
thread->ip4_addr = ip4_addr;
|
||||
|
||||
thread->thread = g_thread_create (lookup_thread_worker, thread, FALSE, NULL);
|
||||
if (!thread->thread) {
|
||||
lookup_thread_free (thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_thread_die (LookupThread *thread)
|
||||
{
|
||||
g_return_if_fail (thread != NULL);
|
||||
|
||||
g_mutex_lock (thread->lock);
|
||||
thread->die = TRUE;
|
||||
g_mutex_unlock (thread->lock);
|
||||
}
|
||||
|
||||
#define INVALID_TAG "invalid"
|
||||
|
||||
static const char *
|
||||
|
|
@ -181,7 +79,7 @@ get_connection_id (NMConnection *connection)
|
|||
}
|
||||
|
||||
static NMDevice *
|
||||
get_best_device (NMManager *manager, NMActRequest **out_req)
|
||||
get_best_ip4_device (NMManager *manager, NMActRequest **out_req)
|
||||
{
|
||||
GSList *devices, *iter;
|
||||
NMDevice *best = NULL;
|
||||
|
|
@ -253,142 +151,107 @@ get_best_device (NMManager *manager, NMActRequest **out_req)
|
|||
return best;
|
||||
}
|
||||
|
||||
#define FALLBACK_HOSTNAME "localhost.localdomain"
|
||||
|
||||
static gboolean
|
||||
update_etc_hosts (const char *hostname, gboolean *out_changed)
|
||||
static NMDevice *
|
||||
get_best_ip6_device (NMManager *manager, NMActRequest **out_req)
|
||||
{
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
GError *error = NULL;
|
||||
GString *new_contents = NULL;
|
||||
gsize contents_len = 0;
|
||||
gboolean success = FALSE;
|
||||
GSList *devices, *iter;
|
||||
NMDevice *best = NULL;
|
||||
int best_prio = G_MAXINT;
|
||||
|
||||
g_return_val_if_fail (hostname != NULL, FALSE);
|
||||
g_return_val_if_fail (out_changed != NULL, FALSE);
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
||||
g_return_val_if_fail (out_req != NULL, NULL);
|
||||
g_return_val_if_fail (*out_req == NULL, NULL);
|
||||
|
||||
if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
devices = nm_manager_get_devices (manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *dev = NM_DEVICE (iter->data);
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMIP6Config *ip6_config;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
int prio;
|
||||
guint i;
|
||||
gboolean can_default = FALSE;
|
||||
const char *method = NULL;
|
||||
|
||||
/* Get the new /etc/hosts contents */
|
||||
lines = g_strsplit_set (contents, "\n\r", 0);
|
||||
new_contents = nm_policy_get_etc_hosts ((const char **) lines,
|
||||
contents_len,
|
||||
hostname,
|
||||
FALLBACK_HOSTNAME,
|
||||
&error);
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED)
|
||||
continue;
|
||||
|
||||
if (new_contents) {
|
||||
nm_log_info (LOGD_DNS, "Updating /etc/hosts with new system hostname");
|
||||
ip6_config = nm_device_get_ip6_config (dev);
|
||||
if (!ip6_config)
|
||||
continue;
|
||||
|
||||
g_clear_error (&error);
|
||||
/* And actually update /etc/hosts */
|
||||
if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
success = TRUE;
|
||||
*out_changed = TRUE;
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
/* Never set the default route through an IPv4LL-addressed device */
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6)
|
||||
method = nm_setting_ip6_config_get_method (s_ip6);
|
||||
|
||||
if (method && !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
||||
continue;
|
||||
|
||||
/* Make sure at least one of this device's IP addresses has a gateway */
|
||||
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
|
||||
NMIP6Address *addr;
|
||||
|
||||
addr = nm_ip6_config_get_address (ip6_config, i);
|
||||
if (nm_ip6_address_get_gateway (addr)) {
|
||||
can_default = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (new_contents, TRUE);
|
||||
} else if (!error) {
|
||||
/* No change required */
|
||||
success = TRUE;
|
||||
} else {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error->code, error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
if (!can_default && !NM_IS_DEVICE_MODEM (dev))
|
||||
continue;
|
||||
|
||||
/* 'never-default' devices can't ever be the default */
|
||||
if (s_ip6 && nm_setting_ip6_config_get_never_default (s_ip6))
|
||||
continue;
|
||||
|
||||
prio = nm_device_get_priority (dev);
|
||||
if (prio > 0 && prio < best_prio) {
|
||||
best = dev;
|
||||
best_prio = prio;
|
||||
*out_req = req;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
return best;
|
||||
}
|
||||
|
||||
static void
|
||||
set_system_hostname (const char *new_hostname, const char *msg)
|
||||
_set_hostname (const char *new_hostname, const char *msg)
|
||||
{
|
||||
char old_hostname[HOST_NAME_MAX + 1];
|
||||
int ret = 0;
|
||||
const char *name = new_hostname ? new_hostname : FALLBACK_HOSTNAME;
|
||||
gboolean set_hostname = TRUE, changed = FALSE;
|
||||
|
||||
old_hostname[HOST_NAME_MAX] = '\0';
|
||||
errno = 0;
|
||||
ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||
errno, strerror (errno));
|
||||
} else {
|
||||
/* Don't set the hostname if it isn't actually changing */
|
||||
if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||
|| (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME)))
|
||||
set_hostname = FALSE;
|
||||
}
|
||||
|
||||
if (set_hostname) {
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||
ret = sethostname (name, strlen (name));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||
name, errno, strerror (errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* But still always try updating /etc/hosts just in case the hostname
|
||||
* changed while NM wasn't running; we need to make sure that /etc/hosts
|
||||
* has valid mappings for '127.0.0.1' and the current system hostname. If
|
||||
* those exist, update_etc_hosts() will just return and won't touch
|
||||
* /etc/hosts at all.
|
||||
*/
|
||||
if (!update_etc_hosts (name, &changed)) {
|
||||
/* error updating /etc/hosts; fallback to localhost.localdomain */
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '" FALLBACK_HOSTNAME "' (error updating /etc/hosts)");
|
||||
ret = sethostname (FALLBACK_HOSTNAME, strlen (FALLBACK_HOSTNAME));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the fallback system hostname (%s): (%d) %s",
|
||||
FALLBACK_HOSTNAME, errno, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
if (nm_policy_set_system_hostname (new_hostname, msg))
|
||||
nm_utils_call_dispatcher ("hostname", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_callback (LookupThread *thread, gpointer user_data)
|
||||
lookup_callback (HostnameThread *thread,
|
||||
int result,
|
||||
const char *hostname,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
char *msg;
|
||||
|
||||
/* If the thread was told to die or it's not the current in-progress
|
||||
* hostname lookup, nothing to do.
|
||||
*/
|
||||
if (thread->die || (thread != policy->lookup))
|
||||
goto done;
|
||||
|
||||
policy->lookup = NULL;
|
||||
if (!strlen (thread->hostname)) {
|
||||
char *msg;
|
||||
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
msg = g_strdup_printf ("address lookup failed: %d", thread->ret);
|
||||
set_system_hostname (NULL, msg);
|
||||
g_free (msg);
|
||||
} else
|
||||
set_system_hostname (thread->hostname, "from address lookup");
|
||||
|
||||
done:
|
||||
lookup_thread_free (thread);
|
||||
/* Update the hostname if the calling lookup thread is the in-progress one */
|
||||
if (!hostname_thread_is_dead (thread) && (thread == policy->lookup)) {
|
||||
policy->lookup = NULL;
|
||||
if (!hostname) {
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
msg = g_strdup_printf ("address lookup failed: %d", result);
|
||||
_set_hostname (NULL, msg);
|
||||
g_free (msg);
|
||||
} else
|
||||
_set_hostname (hostname, "from address lookup");
|
||||
}
|
||||
hostname_thread_free (thread);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -403,7 +266,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
g_return_if_fail (policy != NULL);
|
||||
|
||||
if (policy->lookup) {
|
||||
lookup_thread_die (policy->lookup);
|
||||
hostname_thread_kill (policy->lookup);
|
||||
policy->lookup = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -419,20 +282,20 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
/* Try a persistent hostname first */
|
||||
g_object_get (G_OBJECT (policy->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
|
||||
if (configured_hostname) {
|
||||
set_system_hostname (configured_hostname, "from system configuration");
|
||||
_set_hostname (configured_hostname, "from system configuration");
|
||||
g_free (configured_hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try automatically determined hostname from the best device's IP config */
|
||||
if (!best)
|
||||
best = get_best_device (policy->manager, &best_req);
|
||||
best = get_best_ip4_device (policy->manager, &best_req);
|
||||
|
||||
if (!best) {
|
||||
/* No best device; fall back to original hostname or if there wasn't
|
||||
* one, 'localhost.localdomain'
|
||||
*/
|
||||
set_system_hostname (policy->orig_hostname, "no default device");
|
||||
_set_hostname (policy->orig_hostname, "no default device");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +309,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
/* Sanity check */
|
||||
while (*p) {
|
||||
if (!isblank (*p++)) {
|
||||
set_system_hostname (dhcp4_hostname, "from DHCP");
|
||||
_set_hostname (dhcp4_hostname, "from DHCP");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -459,7 +322,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
* when NM started up.
|
||||
*/
|
||||
if (policy->orig_hostname) {
|
||||
set_system_hostname (policy->orig_hostname, "from system startup");
|
||||
_set_hostname (policy->orig_hostname, "from system startup");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +334,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
|| (nm_ip4_config_get_num_nameservers (ip4_config) == 0)
|
||||
|| (nm_ip4_config_get_num_addresses (ip4_config) == 0)) {
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
set_system_hostname (NULL, "no IPv4 config");
|
||||
_set_hostname (NULL, "no IPv4 config");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -479,15 +342,15 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
g_assert (addr); /* checked for > 1 address above */
|
||||
|
||||
/* Start the hostname lookup thread */
|
||||
policy->lookup = lookup_thread_new (nm_ip4_address_get_address (addr), lookup_callback, policy);
|
||||
policy->lookup = hostname_thread_new (nm_ip4_address_get_address (addr), lookup_callback, policy);
|
||||
if (!policy->lookup) {
|
||||
/* Fall back to 'localhost.localdomain' */
|
||||
set_system_hostname (NULL, "error starting hostname thread");
|
||||
_set_hostname (NULL, "error starting hostname thread");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
NMNamedIPConfigType dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
NMDevice *best = NULL;
|
||||
|
|
@ -501,10 +364,10 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
|||
NMSettingConnection *s_con = NULL;
|
||||
const char *connection_id;
|
||||
|
||||
best = get_best_device (policy->manager, &best_req);
|
||||
best = get_best_ip4_device (policy->manager, &best_req);
|
||||
if (!best)
|
||||
goto out;
|
||||
if (!force_update && (best == policy->default_device))
|
||||
if (!force_update && (best == policy->default_device4))
|
||||
goto out;
|
||||
|
||||
/* If a VPN connection is active, it is preferred */
|
||||
|
|
@ -598,16 +461,149 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
|||
|
||||
connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
|
||||
if (connection_id) {
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for routing and DNS.", connection_id, ip_iface);
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv4 routing and DNS.", connection_id, ip_iface);
|
||||
} else {
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for routing and DNS.", ip_iface);
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for IPv4 routing and DNS.", ip_iface);
|
||||
}
|
||||
|
||||
out:
|
||||
/* Update the system hostname */
|
||||
update_system_hostname (policy, best);
|
||||
policy->default_device4 = best;
|
||||
}
|
||||
|
||||
policy->default_device = best;
|
||||
static void
|
||||
update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
NMNamedIPConfigType dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
NMDevice *best = NULL;
|
||||
NMActRequest *best_req = NULL;
|
||||
NMNamedManager *named_mgr;
|
||||
GSList *devices = NULL, *iter;
|
||||
#if NOT_YET
|
||||
GSList *vpns;
|
||||
#endif
|
||||
NMIP6Config *ip6_config = NULL;
|
||||
NMIP6Address *addr;
|
||||
const char *ip_iface = NULL;
|
||||
NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con = NULL;
|
||||
const char *connection_id;
|
||||
|
||||
best = get_best_ip6_device (policy->manager, &best_req);
|
||||
if (!best)
|
||||
goto out;
|
||||
if (!force_update && (best == policy->default_device6))
|
||||
goto out;
|
||||
|
||||
#if NOT_YET
|
||||
/* If a VPN connection is active, it is preferred */
|
||||
vpns = nm_vpn_manager_get_active_connections (policy->vpn_manager);
|
||||
for (iter = vpns; iter; iter = g_slist_next (iter)) {
|
||||
NMVPNConnection *candidate = NM_VPN_CONNECTION (iter->data);
|
||||
NMConnection *vpn_connection;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean can_default = TRUE;
|
||||
NMVPNConnectionState vpn_state;
|
||||
|
||||
/* If it's marked 'never-default', don't make it default */
|
||||
vpn_connection = nm_vpn_connection_get_connection (candidate);
|
||||
g_assert (vpn_connection);
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (vpn_connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6 && nm_setting_ip6_config_get_never_default (s_ip6))
|
||||
can_default = FALSE;
|
||||
|
||||
vpn_state = nm_vpn_connection_get_vpn_state (candidate);
|
||||
if (can_default && (vpn_state == NM_VPN_CONNECTION_STATE_ACTIVATED)) {
|
||||
NMIP6Config *parent_ip6;
|
||||
NMDevice *parent;
|
||||
|
||||
ip_iface = nm_vpn_connection_get_ip_iface (candidate);
|
||||
connection = nm_vpn_connection_get_connection (candidate);
|
||||
ip6_config = nm_vpn_connection_get_ip6_config (candidate);
|
||||
addr = nm_ip6_config_get_address (ip6_config, 0);
|
||||
|
||||
parent = nm_vpn_connection_get_parent_device (candidate);
|
||||
parent_ip6 = nm_device_get_ip6_config (parent);
|
||||
|
||||
nm_system_replace_default_ip6_route_vpn (ip_iface,
|
||||
nm_ip6_address_get_gateway (addr),
|
||||
nm_vpn_connection_get_ip4_internal_gateway (candidate),
|
||||
nm_ip6_config_get_mss (ip4_config),
|
||||
nm_device_get_ip_iface (parent),
|
||||
nm_ip6_config_get_mss (parent_ip4));
|
||||
|
||||
dns_type = NM_NAMED_IP_CONFIG_TYPE_VPN;
|
||||
}
|
||||
g_object_unref (candidate);
|
||||
}
|
||||
g_slist_free (vpns);
|
||||
#endif
|
||||
|
||||
/* The best device gets the default route if a VPN connection didn't */
|
||||
if (!ip_iface || !ip6_config) {
|
||||
connection = nm_act_request_get_connection (best_req);
|
||||
ip_iface = nm_device_get_ip_iface (best);
|
||||
ip6_config = nm_device_get_ip6_config (best);
|
||||
g_assert (ip6_config);
|
||||
addr = nm_ip6_config_get_address (ip6_config, 0);
|
||||
|
||||
nm_system_replace_default_ip6_route (ip_iface, nm_ip6_address_get_gateway (addr));
|
||||
|
||||
dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
}
|
||||
|
||||
if (!ip_iface || !ip6_config) {
|
||||
nm_log_warn (LOGD_CORE, "couldn't determine IP interface (%p) or IPv6 config (%p)!",
|
||||
ip_iface, ip6_config);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update the default active connection. Only mark the new default
|
||||
* active connection after setting default = FALSE on all other connections
|
||||
* first. The order is important, we don't want two connections marked
|
||||
* default at the same time ever.
|
||||
*/
|
||||
devices = nm_manager_get_devices (policy->manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *dev = NM_DEVICE (iter->data);
|
||||
NMActRequest *req;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
if (req && (req != best_req))
|
||||
nm_act_request_set_default6 (req, FALSE);
|
||||
}
|
||||
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_add_ip6_config (named_mgr, ip_iface, ip6_config, dns_type);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
/* Now set new default active connection _after_ updating DNS info, so that
|
||||
* if the connection is shared dnsmasq picks up the right stuff.
|
||||
*/
|
||||
if (best_req)
|
||||
nm_act_request_set_default6 (best_req, TRUE);
|
||||
|
||||
if (connection)
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
|
||||
connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
|
||||
if (connection_id) {
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv6 routing and DNS.", connection_id, ip_iface);
|
||||
} else {
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for IPv6 routing and DNS.", ip_iface);
|
||||
}
|
||||
|
||||
out:
|
||||
policy->default_device6 = best;
|
||||
}
|
||||
|
||||
static void
|
||||
update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
update_ip4_routing_and_dns (policy, force_update);
|
||||
update_ip6_routing_and_dns (policy, force_update);
|
||||
|
||||
/* Update the system hostname */
|
||||
update_system_hostname (policy, policy->default_device4);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -796,10 +792,23 @@ device_state_changed (NMDevice *device,
|
|||
/* Mark the connection invalid if it failed during activation so that
|
||||
* it doesn't get automatically chosen over and over and over again.
|
||||
*/
|
||||
if (connection && IS_ACTIVATING_STATE (old_state)) {
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
|
||||
nm_connection_clear_secrets (connection);
|
||||
if (connection) {
|
||||
gboolean fail = FALSE;
|
||||
|
||||
if (IS_ACTIVATING_STATE (old_state)) {
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
|
||||
fail = TRUE;
|
||||
} else if ( (old_state == NM_DEVICE_STATE_ACTIVATED)
|
||||
&& (reason == NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED)) {
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid because IP configuration expired.",
|
||||
get_connection_id (connection));
|
||||
fail = TRUE;
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
|
||||
nm_connection_clear_secrets (connection);
|
||||
}
|
||||
}
|
||||
schedule_activate_check (policy, device, 3);
|
||||
break;
|
||||
|
|
@ -828,9 +837,9 @@ device_state_changed (NMDevice *device,
|
|||
}
|
||||
|
||||
static void
|
||||
device_ip4_config_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
device_ip_config_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_routing_and_dns ((NMPolicy *) user_data, TRUE);
|
||||
}
|
||||
|
|
@ -872,7 +881,12 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
|
|||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
|
||||
G_CALLBACK (device_ip4_config_changed),
|
||||
G_CALLBACK (device_ip_config_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG,
|
||||
G_CALLBACK (device_ip_config_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
|
|
@ -1083,7 +1097,7 @@ nm_policy_destroy (NMPolicy *policy)
|
|||
* by the lookup thread callback.
|
||||
*/
|
||||
if (policy->lookup) {
|
||||
lookup_thread_die (policy->lookup);
|
||||
hostname_thread_kill (policy->lookup);
|
||||
policy->lookup = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
271
src/nm-system.c
271
src/nm-system.c
|
|
@ -48,7 +48,7 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
|
||||
/* Because of a bug in libnl, rtnl.h should be included before route.h */
|
||||
#include <netlink/route/rtnl.h>
|
||||
|
|
@ -196,8 +196,10 @@ sync_addresses (const char *iface, int ifindex, int family,
|
|||
struct nl_cache *addr_cache;
|
||||
struct rtnl_addr *filter_addr, *match_addr;
|
||||
struct nl_object *match;
|
||||
struct nl_addr *nladdr;
|
||||
int i, err;
|
||||
guint32 log_domain = (family == AF_INET) ? LOGD_IP4 : LOGD_IP6;
|
||||
char buf[INET6_ADDRSTRLEN + 1];
|
||||
|
||||
log_domain |= LOGD_DEVICE;
|
||||
|
||||
|
|
@ -218,20 +220,22 @@ sync_addresses (const char *iface, int ifindex, int family,
|
|||
if (family)
|
||||
rtnl_addr_set_family (filter_addr, family);
|
||||
|
||||
nm_log_dbg (log_domain, "(%s): syncing addresses (family %d)", iface, family);
|
||||
|
||||
/* Walk through the cache, comparing the addresses already on
|
||||
* the interface to the addresses in addrs.
|
||||
*/
|
||||
for (match = nl_cache_get_first (addr_cache); match; match = nl_cache_get_next (match)) {
|
||||
match_addr = (struct rtnl_addr *)match;
|
||||
gboolean buf_valid = FALSE;
|
||||
match_addr = (struct rtnl_addr *) match;
|
||||
|
||||
/* Skip addresses not on our interface */
|
||||
if (!nl_object_match_filter (match, (struct nl_object *)filter_addr))
|
||||
if (!nl_object_match_filter (match, (struct nl_object *) filter_addr))
|
||||
continue;
|
||||
|
||||
if (addrs) {
|
||||
for (i = 0; i < num_addrs; i++) {
|
||||
if (addrs[i] &&
|
||||
nl_object_identical (match, (struct nl_object *)addrs[i]))
|
||||
if (addrs[i] && nl_object_identical (match, (struct nl_object *) addrs[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -245,10 +249,31 @@ sync_addresses (const char *iface, int ifindex, int family,
|
|||
}
|
||||
}
|
||||
|
||||
nladdr = rtnl_addr_get_local (match_addr);
|
||||
|
||||
/* Don't delete IPv6 link-local addresses; they don't belong to NM */
|
||||
if (rtnl_addr_get_family (match_addr) == AF_INET6 &&
|
||||
rtnl_addr_get_scope (match_addr) == RT_SCOPE_LINK) {
|
||||
continue;
|
||||
if (rtnl_addr_get_family (match_addr) == AF_INET6) {
|
||||
struct in6_addr *tmp;
|
||||
|
||||
if (rtnl_addr_get_scope (match_addr) == RT_SCOPE_LINK) {
|
||||
nm_log_dbg (log_domain, "(%s): ignoring IPv6 link-local address", iface);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = nl_addr_get_binary_addr (nladdr);
|
||||
if (inet_ntop (AF_INET6, tmp, buf, sizeof (buf)))
|
||||
buf_valid = TRUE;
|
||||
} else if (rtnl_addr_get_family (match_addr) == AF_INET) {
|
||||
struct in_addr *tmp;
|
||||
|
||||
tmp = nl_addr_get_binary_addr (nladdr);
|
||||
if (inet_ntop (AF_INET, tmp, buf, sizeof (buf)))
|
||||
buf_valid = TRUE;
|
||||
}
|
||||
|
||||
if (buf_valid) {
|
||||
nm_log_dbg (log_domain, "(%s): removing address '%s/%d'",
|
||||
iface, buf, nl_addr_get_prefixlen (nladdr));
|
||||
}
|
||||
|
||||
/* Otherwise, match_addr should be removed from the interface. */
|
||||
|
|
@ -264,9 +289,29 @@ sync_addresses (const char *iface, int ifindex, int family,
|
|||
|
||||
/* Now add the remaining new addresses */
|
||||
for (i = 0; i < num_addrs; i++) {
|
||||
struct in6_addr *in6tmp;
|
||||
struct in_addr *in4tmp;
|
||||
gboolean buf_valid = FALSE;
|
||||
|
||||
if (!addrs[i])
|
||||
continue;
|
||||
|
||||
nladdr = rtnl_addr_get_local (addrs[i]);
|
||||
if (rtnl_addr_get_family (addrs[i]) == AF_INET6) {
|
||||
in6tmp = nl_addr_get_binary_addr (nladdr);
|
||||
if (inet_ntop (AF_INET6, in6tmp, buf, sizeof (buf)))
|
||||
buf_valid = TRUE;
|
||||
} else if (rtnl_addr_get_family (addrs[i]) == AF_INET) {
|
||||
in4tmp = nl_addr_get_binary_addr (nladdr);
|
||||
if (inet_ntop (AF_INET, in4tmp, buf, sizeof (buf)))
|
||||
buf_valid = TRUE;
|
||||
}
|
||||
|
||||
if (buf_valid) {
|
||||
nm_log_dbg (log_domain, "(%s): adding address '%s/%d'",
|
||||
iface, buf, nl_addr_get_prefixlen (nladdr));
|
||||
}
|
||||
|
||||
err = rtnl_addr_add (nlh, addrs[i], 0);
|
||||
if (err < 0) {
|
||||
nm_log_err (log_domain,
|
||||
|
|
@ -460,7 +505,7 @@ nm_system_device_set_ip6_route (const char *iface,
|
|||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
/* Destination */
|
||||
dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *)ip6_dest, sizeof (*ip6_dest));
|
||||
dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_dest, sizeof (*ip6_dest));
|
||||
g_return_val_if_fail (dest_addr != NULL, NULL);
|
||||
nl_addr_set_prefixlen (dest_addr, (int) ip6_prefix);
|
||||
|
||||
|
|
@ -469,7 +514,7 @@ nm_system_device_set_ip6_route (const char *iface,
|
|||
|
||||
/* Gateway */
|
||||
if (ip6_gateway && !IN6_IS_ADDR_UNSPECIFIED (ip6_gateway)) {
|
||||
gw_addr = nl_addr_build (AF_INET6, (struct in6_addr *)ip6_gateway, sizeof (*ip6_gateway));
|
||||
gw_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_gateway, sizeof (*ip6_gateway));
|
||||
if (gw_addr) {
|
||||
rtnl_route_set_gateway (route, gw_addr);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||
|
|
@ -940,6 +985,153 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
|
|||
return success;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct nl_handle *nlh;
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_addr *gw_addr = NULL;
|
||||
int iface_idx, err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, NULL);
|
||||
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx < 0)
|
||||
return NULL;
|
||||
|
||||
/* Gateway might be over a bridge; try adding a route to gateway first */
|
||||
route = rtnl_route_alloc ();
|
||||
if (route == NULL)
|
||||
return NULL;
|
||||
|
||||
rtnl_route_set_family (route, AF_INET6);
|
||||
rtnl_route_set_table (route, RT_TABLE_MAIN);
|
||||
rtnl_route_set_oif (route, iface_idx);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_LINK);
|
||||
|
||||
gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw));
|
||||
if (!gw_addr)
|
||||
goto error;
|
||||
nl_addr_set_prefixlen (gw_addr, 128);
|
||||
rtnl_route_set_dst (route, gw_addr);
|
||||
nl_addr_put (gw_addr);
|
||||
|
||||
/* Add direct route to the gateway */
|
||||
err = rtnl_route_add (nlh, route, 0);
|
||||
if (err) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to add IPv4 route to gateway (%d)",
|
||||
iface, err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return route;
|
||||
|
||||
error:
|
||||
rtnl_route_put (route);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_handle *nlh;
|
||||
struct nl_addr *gw_addr = NULL;
|
||||
int iface_idx, err = -1;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, -ENODEV);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, -ENOMEM);
|
||||
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx < 0)
|
||||
return -ENODEV;
|
||||
|
||||
route = rtnl_route_alloc();
|
||||
g_return_val_if_fail (route != NULL, -ENOMEM);
|
||||
|
||||
rtnl_route_set_family (route, AF_INET6);
|
||||
rtnl_route_set_table (route, RT_TABLE_MAIN);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||
rtnl_route_set_oif (route, iface_idx);
|
||||
|
||||
if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) {
|
||||
/* Build up the gateway address */
|
||||
gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw));
|
||||
if (!gw_addr) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
nl_addr_set_prefixlen (gw_addr, -1);
|
||||
rtnl_route_set_gateway (route, gw_addr);
|
||||
}
|
||||
|
||||
/* Add the new default route */
|
||||
err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
|
||||
if (err == -EEXIST) {
|
||||
/* FIXME: even though we use NLM_F_REPLACE the kernel won't replace
|
||||
* the route if it's the same. Should try to remove it first, then
|
||||
* add the new one again here.
|
||||
*/
|
||||
err = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
if (gw_addr)
|
||||
nl_addr_put (gw_addr);
|
||||
rtnl_route_put (route);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_replace_default_ip6_route
|
||||
*
|
||||
* Replace default IPv6 route with one via the given gateway
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
struct nl_handle *nlh;
|
||||
gboolean success = FALSE;
|
||||
int err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, FALSE);
|
||||
|
||||
err = replace_default_ip6_route (iface, gw);
|
||||
if (err == 0) {
|
||||
return TRUE;
|
||||
} else if (err != -ESRCH) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route: %d",
|
||||
iface, err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip6_route_to_gateway (iface, gw);
|
||||
if (!gw_route)
|
||||
return FALSE;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip6_route (iface, gw);
|
||||
if (err != 0) {
|
||||
rtnl_route_del (nlh, gw_route, 0);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void flush_addresses (const char *iface, gboolean ipv4_only)
|
||||
{
|
||||
int iface_idx;
|
||||
|
|
@ -947,7 +1139,7 @@ static void flush_addresses (const char *iface, gboolean ipv4_only)
|
|||
g_return_if_fail (iface != NULL);
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx >= 0)
|
||||
sync_addresses (iface, iface_idx, ipv4_only ? AF_INET : 0, NULL, 0);
|
||||
sync_addresses (iface, iface_idx, ipv4_only ? AF_INET : AF_UNSPEC, NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -986,7 +1178,7 @@ foreach_route (void (*callback)(struct nl_object *, gpointer),
|
|||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
route_cache = rtnl_route_alloc_cache (nlh);
|
||||
nl_cache_mngt_provide (route_cache);
|
||||
g_assert (route_cache);
|
||||
nl_cache_foreach (route_cache, callback, user_data);
|
||||
nl_cache_free (route_cache);
|
||||
}
|
||||
|
|
@ -1011,6 +1203,25 @@ check_one_route (struct nl_object *object, void *user_data)
|
|||
if (data->family && rtnl_route_get_family (route) != data->family)
|
||||
return;
|
||||
|
||||
/* We don't want to flush IPv6 link-local routes that may exist on the
|
||||
* the interface since the LL address and routes should normally stay
|
||||
* assigned all the time.
|
||||
*/
|
||||
if ( (data->family == AF_INET6 || data->family == AF_UNSPEC)
|
||||
&& (rtnl_route_get_family (route) == AF_INET6)) {
|
||||
struct nl_addr *nl;
|
||||
struct in6_addr *addr = NULL;
|
||||
|
||||
nl = rtnl_route_get_dst (route);
|
||||
if (nl)
|
||||
addr = nl_addr_get_binary_addr (nl);
|
||||
|
||||
if (addr) {
|
||||
if (IN6_IS_ADDR_LINKLOCAL (addr) || IN6_IS_ADDR_MC_LINKLOCAL (addr))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
err = rtnl_route_del (nm_netlink_get_default_handle (), route, 0);
|
||||
if (err < 0) {
|
||||
nm_log_err (LOGD_DEVICE,
|
||||
|
|
@ -1019,21 +1230,25 @@ check_one_route (struct nl_object *object, void *user_data)
|
|||
}
|
||||
}
|
||||
|
||||
static void flush_routes (const char *iface, gboolean ipv4_only)
|
||||
static void flush_routes (int ifindex, const char *iface, int family)
|
||||
{
|
||||
int iface_idx;
|
||||
RouteCheckData check_data;
|
||||
|
||||
g_return_if_fail (iface != NULL);
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx >= 0) {
|
||||
memset (&check_data, 0, sizeof (check_data));
|
||||
check_data.iface = iface;
|
||||
check_data.iface_idx = iface_idx;
|
||||
check_data.family = ipv4_only ? AF_INET : 0;
|
||||
|
||||
foreach_route (check_one_route, &check_data);
|
||||
if (ifindex < 0) {
|
||||
ifindex = nm_netlink_iface_to_index (iface);
|
||||
if (ifindex < 0) {
|
||||
nm_log_dbg (LOGD_DEVICE, "(%s) failed to lookup interface index", iface);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset (&check_data, 0, sizeof (check_data));
|
||||
check_data.iface = iface;
|
||||
check_data.iface_idx = ifindex;
|
||||
check_data.family = family;
|
||||
foreach_route (check_one_route, &check_data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1042,23 +1257,25 @@ static void flush_routes (const char *iface, gboolean ipv4_only)
|
|||
* Flush all network addresses associated with a network device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_flush_routes (NMDevice *dev)
|
||||
void nm_system_device_flush_routes (NMDevice *dev, int family)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
flush_routes (nm_device_get_ip_iface (dev),
|
||||
nm_device_get_ip6_config (dev) == NULL);
|
||||
flush_routes (nm_device_get_ip_ifindex (dev),
|
||||
nm_device_get_ip_iface (dev),
|
||||
family);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_flush_routes_with_iface
|
||||
*
|
||||
* Flush all routes associated with a network device
|
||||
* Flush all routes associated with a network device. 'family' is an
|
||||
* address family, either AF_INET, AF_INET6, or AF_UNSPEC.
|
||||
*
|
||||
*/
|
||||
void nm_system_device_flush_routes_with_iface (const char *iface)
|
||||
void nm_system_device_flush_routes_with_iface (const char *iface, int family)
|
||||
{
|
||||
flush_routes (iface, FALSE);
|
||||
flush_routes (-1, iface, family);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -33,13 +33,16 @@
|
|||
* implemented in the backend files in backends/ directory
|
||||
*/
|
||||
|
||||
void nm_system_device_flush_routes (NMDevice *dev);
|
||||
void nm_system_device_flush_routes_with_iface (const char *iface);
|
||||
void nm_system_device_flush_routes (NMDevice *dev, int family);
|
||||
void nm_system_device_flush_routes_with_iface (const char *iface, int family);
|
||||
|
||||
gboolean nm_system_replace_default_ip4_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss);
|
||||
|
||||
gboolean nm_system_replace_default_ip6_route (const char *iface,
|
||||
const struct in6_addr *gw);
|
||||
|
||||
gboolean nm_system_replace_default_ip4_route_vpn (const char *iface,
|
||||
guint32 ext_gw,
|
||||
guint32 int_gw,
|
||||
|
|
|
|||
|
|
@ -384,11 +384,11 @@ device_creator (NMUdevManager *manager,
|
|||
}
|
||||
|
||||
if (is_olpc_mesh (udev_device)) /* must be before is_wireless */
|
||||
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver);
|
||||
else if (is_wireless (udev_device))
|
||||
device = (GObject *) nm_device_wifi_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_wifi_new (path, ifname, driver);
|
||||
else
|
||||
device = (GObject *) nm_device_ethernet_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_ethernet_new (path, ifname, driver);
|
||||
|
||||
out:
|
||||
if (grandparent)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ test_policy_hosts_CPPFLAGS = \
|
|||
$(GLIB_CFLAGS)
|
||||
|
||||
test_policy_hosts_LDADD = \
|
||||
-ldl \
|
||||
$(top_builddir)/src/libtest-policy-hosts.la \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-named-manager.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-glib-compat.h"
|
||||
|
||||
#include "nm-vpn-connection-glue.h"
|
||||
|
|
@ -69,6 +69,7 @@ typedef struct {
|
|||
gulong device_ip4;
|
||||
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
NMActiveConnectionState state;
|
||||
|
||||
NMVPNConnectionState vpn_state;
|
||||
|
|
@ -102,6 +103,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
PROP_VPN,
|
||||
PROP_VPN_STATE,
|
||||
PROP_BANNER,
|
||||
|
|
@ -876,7 +878,8 @@ vpn_cleanup (NMVPNConnection *connection)
|
|||
|
||||
if (priv->tundev) {
|
||||
nm_system_device_set_up_down_with_iface (priv->tundev, FALSE, NULL);
|
||||
nm_system_device_flush_routes_with_iface (priv->tundev);
|
||||
/* FIXME: use AF_UNSPEC here when we have IPv6 support */
|
||||
nm_system_device_flush_routes_with_iface (priv->tundev, AF_INET);
|
||||
nm_system_device_flush_addresses_with_iface (priv->tundev);
|
||||
}
|
||||
|
||||
|
|
@ -1052,6 +1055,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, priv->is_default);
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, priv->is_default6);
|
||||
break;
|
||||
case PROP_VPN:
|
||||
g_value_set_boolean (value, TRUE);
|
||||
break;
|
||||
|
|
@ -1122,7 +1128,14 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
|
|||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
|
|
|
|||
|
|
@ -1215,7 +1215,10 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) {
|
||||
if (valid_ip6_config) {
|
||||
/* Nope, no IPv4 */
|
||||
goto done;
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||
NULL);
|
||||
return NM_SETTING (s_ip4);
|
||||
}
|
||||
|
||||
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
||||
|
|
@ -1230,6 +1233,7 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE),
|
||||
NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE),
|
||||
NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
|
||||
NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", TRUE),
|
||||
NULL);
|
||||
|
||||
/* Handle manual settings */
|
||||
|
|
@ -1485,6 +1489,7 @@ make_ip6_setting (shvarFile *ifcfg,
|
|||
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE),
|
||||
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE),
|
||||
NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
|
||||
NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
|
||||
NULL);
|
||||
|
||||
if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
|
|
|
|||
|
|
@ -16,3 +16,4 @@ IPV6INIT=yes
|
|||
IPV6_AUTOCONF=no
|
||||
IPV6ADDR="1001:abba::1234/56"
|
||||
IPV6ADDR_SECONDARIES="2001:abba::2234/64 3001:abba::3234/96"
|
||||
IPV6_FAILURE_FATAL=no
|
||||
|
|
|
|||
|
|
@ -560,6 +560,13 @@ test_read_wired_static (const char *file, const char *expected_id)
|
|||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
/* Implicit may-fail */
|
||||
ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == FALSE,
|
||||
"wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
|
||||
file,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_MAY_FAIL);
|
||||
|
||||
/* DNS Addresses */
|
||||
ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
|
||||
"wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
|
|
@ -648,6 +655,13 @@ test_read_wired_static (const char *file, const char *expected_id)
|
|||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_METHOD);
|
||||
|
||||
/* Implicit may-fail */
|
||||
ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE,
|
||||
"wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
|
||||
file,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_MAY_FAIL);
|
||||
|
||||
/* DNS Addresses */
|
||||
ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
|
||||
"wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
|
||||
|
|
@ -2011,6 +2025,12 @@ test_read_wired_ipv6_manual (void)
|
|||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
|
||||
|
||||
ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE,
|
||||
"wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_WIRED_IPV6_MANUAL,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_MAY_FAIL);
|
||||
|
||||
/* IP addresses */
|
||||
ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 3,
|
||||
"wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
|
||||
|
|
@ -2165,6 +2185,7 @@ test_read_wired_ipv6_only (void)
|
|||
const char *expected_dns1 = "1:2:3:4::a";
|
||||
NMIP6Address *ip6_addr;
|
||||
struct in6_addr addr;
|
||||
const char *method;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY,
|
||||
NULL,
|
||||
|
|
@ -2217,11 +2238,18 @@ test_read_wired_ipv6_only (void)
|
|||
/* ===== IPv4 SETTING ===== */
|
||||
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
|
||||
ASSERT (s_ip4 == NULL,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s setting",
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_WIRED_IPV6_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_WIRED_IPV6_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
/* ===== IPv6 SETTING ===== */
|
||||
|
||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
|
||||
|
|
@ -5149,6 +5177,7 @@ test_write_wired_static (void)
|
|||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE,
|
||||
NULL);
|
||||
|
||||
addr = nm_ip4_address_new ();
|
||||
|
|
@ -5180,6 +5209,7 @@ test_write_wired_static (void)
|
|||
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||
NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
|
||||
NULL);
|
||||
|
||||
/* Add addresses */
|
||||
|
|
@ -5408,6 +5438,7 @@ test_write_wired_static_ip6_only (void)
|
|||
NMConnection *reread;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
|
||||
GByteArray *mac;
|
||||
|
|
@ -5461,6 +5492,17 @@ test_write_wired_static_ip6_only (void)
|
|||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
|
||||
g_byte_array_free (mac, TRUE);
|
||||
|
||||
/* IP4 setting */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"wired-static-ip6-only-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||
NULL);
|
||||
|
||||
/* IP6 setting */
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
ASSERT (s_ip6 != NULL,
|
||||
|
|
@ -5517,9 +5559,6 @@ test_write_wired_static_ip6_only (void)
|
|||
ASSERT (nm_connection_verify (reread, &error),
|
||||
"wired-static-ip6-only-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
|
||||
|
||||
ASSERT (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG) == NULL,
|
||||
"wired-static-ip6-only-write-reread-verify", "unexpected IPv4 setting");
|
||||
|
||||
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
|
||||
"wired-static-ip6-only-write", "written and re-read connection weren't the same.");
|
||||
|
||||
|
|
|
|||
|
|
@ -934,9 +934,17 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
guint32 i, num;
|
||||
GString *searches;
|
||||
gboolean success = FALSE;
|
||||
const char *method = NULL;
|
||||
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (!s_ip4) {
|
||||
if (s_ip4)
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
/* Missing IP4 setting is assumed to be DHCP */
|
||||
if (!method)
|
||||
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
||||
|
||||
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
int result;
|
||||
|
||||
/* IPv4 disabled, clear IPv4 related parameters */
|
||||
|
|
@ -1079,6 +1087,10 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
svSetValue (ifcfg, "DHCP_CLIENT_ID", value, FALSE);
|
||||
}
|
||||
|
||||
svSetValue (ifcfg, "IPV4_FAILURE_FATAL",
|
||||
nm_setting_ip4_config_get_may_fail (s_ip4) ? "no" : "yes",
|
||||
FALSE);
|
||||
|
||||
/* Static routes - route-<name> file */
|
||||
route_path = utils_get_route_path (ifcfg->fileName);
|
||||
if (!route_path) {
|
||||
|
|
@ -1365,6 +1377,10 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
FALSE);
|
||||
}
|
||||
|
||||
svSetValue (ifcfg, "IPV6_FAILURE_FATAL",
|
||||
nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes",
|
||||
FALSE);
|
||||
|
||||
/* Static routes go to route6-<dev> file */
|
||||
route6_path = utils_get_route6_path (ifcfg->fileName);
|
||||
if (!route6_path) {
|
||||
|
|
|
|||
|
|
@ -337,13 +337,30 @@ split_prefix (char *addr)
|
|||
return slash;
|
||||
}
|
||||
|
||||
static char *
|
||||
split_gw (char *str)
|
||||
{
|
||||
char *comma;
|
||||
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
|
||||
/* Find the prefix and split the string */
|
||||
comma = strchr (str, ',');
|
||||
if (comma && comma > str) {
|
||||
comma++;
|
||||
*(comma - 1) = '\0';
|
||||
return comma;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
read_ip6_addresses (GKeyFile *file,
|
||||
const char *setting_name,
|
||||
const char *key)
|
||||
{
|
||||
GPtrArray *addresses;
|
||||
struct in6_addr addr;
|
||||
struct in6_addr addr, gw;
|
||||
guint32 prefix;
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -351,10 +368,11 @@ read_ip6_addresses (GKeyFile *file,
|
|||
|
||||
/* Look for individual addresses */
|
||||
while (i++ < 1000) {
|
||||
char *tmp, *key_name, *str_prefix;
|
||||
char *tmp, *key_name, *str_prefix, *str_gw;
|
||||
int ret;
|
||||
GValueArray *values;
|
||||
GByteArray *address;
|
||||
GByteArray *gateway;
|
||||
GValue value = { 0 };
|
||||
|
||||
key_name = g_strdup_printf ("%s%d", key, i);
|
||||
|
|
@ -377,6 +395,7 @@ read_ip6_addresses (GKeyFile *file,
|
|||
g_value_array_free (values);
|
||||
goto next;
|
||||
}
|
||||
|
||||
address = g_byte_array_new ();
|
||||
g_byte_array_append (address, (guint8 *) addr.s6_addr, 16);
|
||||
g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
|
|
@ -401,6 +420,26 @@ read_ip6_addresses (GKeyFile *file,
|
|||
g_value_array_append (values, &value);
|
||||
g_value_unset (&value);
|
||||
|
||||
/* Gateway (optional) */
|
||||
str_gw = split_gw (str_prefix);
|
||||
if (str_gw) {
|
||||
ret = inet_pton (AF_INET6, str_gw, &gw);
|
||||
if (ret <= 0) {
|
||||
g_warning ("%s: ignoring invalid IPv6 %s gateway '%s'", __func__, key_name, tmp);
|
||||
g_value_array_free (values);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED (&gw)) {
|
||||
gateway = g_byte_array_new ();
|
||||
g_byte_array_append (gateway, (guint8 *) gw.s6_addr, 16);
|
||||
g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
g_value_take_boxed (&value, gateway);
|
||||
g_value_array_append (values, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
|
||||
g_ptr_array_add (addresses, values);
|
||||
|
||||
next:
|
||||
|
|
@ -422,7 +461,6 @@ ip6_addr_parser (NMSetting *setting, const char *key, GKeyFile *keyfile)
|
|||
const char *setting_name = nm_setting_get_name (setting);
|
||||
|
||||
addresses = read_ip6_addresses (keyfile, setting_name, key);
|
||||
|
||||
if (addresses) {
|
||||
g_object_set (setting, key, addresses, NULL);
|
||||
g_ptr_array_foreach (addresses, free_one_ip6_address, NULL);
|
||||
|
|
|
|||
|
|
@ -226,18 +226,27 @@ ip6_dns_writer (GKeyFile *file,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
ip6_array_to_addr (GValueArray *values, guint32 idx, char *buf, size_t buflen)
|
||||
ip6_array_to_addr (GValueArray *values,
|
||||
guint32 idx,
|
||||
char *buf,
|
||||
size_t buflen,
|
||||
gboolean *out_is_unspec)
|
||||
{
|
||||
GByteArray *byte_array;
|
||||
GValue *addr_val;
|
||||
struct in6_addr *addr;
|
||||
|
||||
g_return_val_if_fail (buflen >= INET6_ADDRSTRLEN, FALSE);
|
||||
|
||||
/* address */
|
||||
addr_val = g_value_array_get_nth (values, idx);
|
||||
byte_array = g_value_get_boxed (addr_val);
|
||||
addr = (struct in6_addr *) byte_array->data;
|
||||
|
||||
if (out_is_unspec && IN6_IS_ADDR_UNSPECIFIED (addr))
|
||||
*out_is_unspec = TRUE;
|
||||
|
||||
errno = 0;
|
||||
if (!inet_ntop (AF_INET6, (struct in6_addr *) byte_array->data, buf, buflen)) {
|
||||
if (!inet_ntop (AF_INET6, addr, buf, buflen)) {
|
||||
GString *ip6_str = g_string_sized_new (INET6_ADDRSTRLEN + 10);
|
||||
|
||||
/* error converting the address */
|
||||
|
|
@ -259,18 +268,24 @@ ip6_array_to_addr_prefix (GValueArray *values)
|
|||
GValue *prefix_val;
|
||||
char *ret = NULL;
|
||||
GString *ip6_str;
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
char buf[INET6_ADDRSTRLEN + 1];
|
||||
gboolean is_unspec = FALSE;
|
||||
|
||||
/* address */
|
||||
if (ip6_array_to_addr (values, 0, buf, sizeof (buf))) {
|
||||
if (ip6_array_to_addr (values, 0, buf, sizeof (buf), NULL)) {
|
||||
/* Enough space for the address, '/', and the prefix */
|
||||
ip6_str = g_string_sized_new (INET6_ADDRSTRLEN + 5);
|
||||
ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5);
|
||||
|
||||
/* prefix */
|
||||
g_string_append (ip6_str, buf);
|
||||
prefix_val = g_value_array_get_nth (values, 1);
|
||||
g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val));
|
||||
|
||||
if (ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec)) {
|
||||
if (!is_unspec)
|
||||
g_string_append_printf (ip6_str, ",%s", buf);
|
||||
}
|
||||
|
||||
ret = ip6_str->str;
|
||||
g_string_free (ip6_str, FALSE);
|
||||
}
|
||||
|
|
@ -298,9 +313,9 @@ ip6_addr_writer (GKeyFile *file,
|
|||
GValueArray *values = g_ptr_array_index (array, i);
|
||||
char *key_name, *ip6_addr;
|
||||
|
||||
if (values->n_values % 2) {
|
||||
nm_warning ("%s: error writing IP6 address %d; address array length"
|
||||
" %d is not a multiple of 2.",
|
||||
if (values->n_values != 3) {
|
||||
nm_warning ("%s: error writing IP6 address %d (address array length "
|
||||
"%d is not 3)",
|
||||
__func__, i, values->n_values);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -337,7 +352,8 @@ ip6_route_writer (GKeyFile *file,
|
|||
GValueArray *values = g_ptr_array_index (array, i);
|
||||
char *key_name;
|
||||
guint32 int_val;
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
char buf[INET6_ADDRSTRLEN + 1];
|
||||
gboolean is_unspec = FALSE;
|
||||
|
||||
memset (list, 0, sizeof (list));
|
||||
|
||||
|
|
@ -347,7 +363,9 @@ ip6_route_writer (GKeyFile *file,
|
|||
continue;
|
||||
|
||||
/* Next Hop */
|
||||
if (!ip6_array_to_addr (values, 2, buf, sizeof (buf)))
|
||||
if (!ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec))
|
||||
continue;
|
||||
if (is_unspec)
|
||||
continue;
|
||||
list[1] = g_strdup (buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ EXTRA_DIST = \
|
|||
Test_Wired_Connection \
|
||||
Test_GSM_Connection \
|
||||
Test_Wireless_Connection \
|
||||
Test_Wired_Connection_MAC_Case
|
||||
Test_Wired_Connection_MAC_Case \
|
||||
Test_Wired_Connection_IP6
|
||||
|
||||
check-local:
|
||||
@for f in $(EXTRA_DIST); do \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
[connection]
|
||||
id=Test Wired Connection IP6
|
||||
uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
|
||||
type=802-3-ethernet
|
||||
autoconnect=true
|
||||
timestamp=6654332
|
||||
|
||||
[802-3-ethernet]
|
||||
auto-negotiate=true
|
||||
mtu=1400
|
||||
|
||||
[ipv4]
|
||||
method=disabled
|
||||
|
||||
[ipv6]
|
||||
method=manual
|
||||
addresses1=abcd:1234:ffff::cdde/64,abcd:1234:ffff::cdd1
|
||||
dns=1111:dddd::aaaa;1::cafe;
|
||||
|
||||
|
|
@ -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.
|
||||
*
|
||||
* Copyright (C) 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -510,7 +510,8 @@ add_one_ip4_route (NMSettingIP4Config *s_ip4,
|
|||
static void
|
||||
add_one_ip6_address (NMSettingIP6Config *s_ip6,
|
||||
const char *addr,
|
||||
guint32 prefix)
|
||||
guint32 prefix,
|
||||
const char *gw)
|
||||
{
|
||||
struct in6_addr tmp;
|
||||
NMIP6Address *ip6_addr;
|
||||
|
|
@ -521,6 +522,11 @@ add_one_ip6_address (NMSettingIP6Config *s_ip6,
|
|||
inet_pton (AF_INET6, addr, &tmp);
|
||||
nm_ip6_address_set_address (ip6_addr, &tmp);
|
||||
|
||||
if (gw) {
|
||||
inet_pton (AF_INET6, gw, &tmp);
|
||||
nm_ip6_address_set_gateway (ip6_addr, &tmp);
|
||||
}
|
||||
|
||||
nm_setting_ip6_config_add_address (s_ip6, ip6_addr);
|
||||
nm_ip6_address_unref (ip6_addr);
|
||||
}
|
||||
|
|
@ -666,8 +672,8 @@ test_write_wired_connection (void)
|
|||
NULL);
|
||||
|
||||
/* Addresses */
|
||||
add_one_ip6_address (s_ip6, address6_1, 64);
|
||||
add_one_ip6_address (s_ip6, address6_2, 56);
|
||||
add_one_ip6_address (s_ip6, address6_1, 64, NULL);
|
||||
add_one_ip6_address (s_ip6, address6_2, 56, NULL);
|
||||
|
||||
/* Routes */
|
||||
add_one_ip6_route (s_ip6, route6_1, route6_1_nh, 64, 3);
|
||||
|
|
@ -708,6 +714,266 @@ test_write_wired_connection (void)
|
|||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
#define TEST_WIRED_IP6_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_IP6"
|
||||
|
||||
static void
|
||||
test_read_ip6_wired_connection (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
GError *error = NULL;
|
||||
const char *tmp;
|
||||
const char *expected_id = "Test Wired Connection IP6";
|
||||
const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
|
||||
struct in6_addr addr6;
|
||||
const char *expected6_address1 = "abcd:1234:ffff::cdde";
|
||||
const char *expected6_gw1 = "abcd:1234:ffff::cdd1";
|
||||
NMIP6Address *ip6_addr;
|
||||
|
||||
connection = connection_from_file (TEST_WIRED_IP6_FILE);
|
||||
ASSERT (connection != NULL,
|
||||
"connection-read", "failed to read %s", TEST_WIRED_IP6_FILE);
|
||||
|
||||
ASSERT (nm_connection_verify (connection, &error),
|
||||
"connection-verify", "failed to verify %s: %s", TEST_WIRED_IP6_FILE, error->message);
|
||||
|
||||
/* ===== CONNECTION SETTING ===== */
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
|
||||
ASSERT (s_con != NULL,
|
||||
"connection-verify-connection", "failed to verify %s: missing %s setting",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
|
||||
/* ID */
|
||||
tmp = nm_setting_connection_get_id (s_con);
|
||||
ASSERT (tmp != NULL,
|
||||
"connection-verify-connection", "failed to verify %s: missing %s / %s key",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
ASSERT (strcmp (tmp, expected_id) == 0,
|
||||
"connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_ID);
|
||||
|
||||
/* UUID */
|
||||
tmp = nm_setting_connection_get_uuid (s_con);
|
||||
ASSERT (tmp != NULL,
|
||||
"connection-verify-connection", "failed to verify %s: missing %s / %s key",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_UUID);
|
||||
ASSERT (strcmp (tmp, expected_uuid) == 0,
|
||||
"connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_UUID);
|
||||
|
||||
/* ===== WIRED SETTING ===== */
|
||||
|
||||
s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
|
||||
ASSERT (s_wired != NULL,
|
||||
"connection-verify-wired", "failed to verify %s: missing %s setting",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_WIRED_SETTING_NAME);
|
||||
|
||||
/* ===== IPv4 SETTING ===== */
|
||||
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"connection-verify-ip4", "failed to verify %s: missing %s setting",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
|
||||
/* Method */
|
||||
tmp = nm_setting_ip4_config_get_method (s_ip4);
|
||||
ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
|
||||
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 0,
|
||||
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_DNS);
|
||||
|
||||
/* ===== IPv6 SETTING ===== */
|
||||
|
||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
|
||||
ASSERT (s_ip6 != NULL,
|
||||
"connection-verify-ip6", "failed to verify %s: missing %s setting",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME);
|
||||
|
||||
/* Method */
|
||||
tmp = nm_setting_ip6_config_get_method (s_ip6);
|
||||
ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
|
||||
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_METHOD);
|
||||
|
||||
ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
|
||||
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_DNS);
|
||||
|
||||
/* Address #1 */
|
||||
ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
|
||||
ASSERT (ip6_addr,
|
||||
"connection-verify-wired", "failed to verify %s: missing IP6 address #1",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
|
||||
ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64,
|
||||
"connection-verify-wired", "failed to verify %s: unexpected IP6 address #1 prefix",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
|
||||
ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0,
|
||||
"connection-verify-wired", "failed to verify %s: couldn't convert IP address #1",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
|
||||
"connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
|
||||
ASSERT (inet_pton (AF_INET6, expected6_gw1, &addr6) > 0,
|
||||
"connection-verify-wired", "failed to verify %s: couldn't convert GW address #1",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_gateway (ip6_addr), &addr6),
|
||||
"connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
|
||||
TEST_WIRED_IP6_FILE,
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_ip6_wired_connection (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
char *uuid;
|
||||
gboolean success;
|
||||
NMConnection *reread;
|
||||
char *testfile = NULL;
|
||||
GError *error = NULL;
|
||||
pid_t owner_grp;
|
||||
uid_t owner_uid;
|
||||
struct in6_addr addr6;
|
||||
const char *dns = "1::cafe";
|
||||
const char *address = "abcd::beef";
|
||||
const char *gw = "dcba::beef";
|
||||
|
||||
connection = nm_connection_new ();
|
||||
ASSERT (connection != NULL,
|
||||
"connection-write", "failed to allocate new connection");
|
||||
|
||||
/* Connection setting */
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
|
||||
ASSERT (s_con != NULL,
|
||||
"connection-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_ID, "Work Wired IP6",
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
/* Wired setting */
|
||||
|
||||
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
|
||||
ASSERT (s_wired != NULL,
|
||||
"connection-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_WIRED_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
|
||||
/* IP4 setting */
|
||||
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"connection-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||
NULL);
|
||||
|
||||
/* IP6 setting */
|
||||
|
||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
|
||||
ASSERT (s_ip6 != NULL,
|
||||
"connection-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_IP6_CONFIG_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
|
||||
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||
NULL);
|
||||
|
||||
/* Addresses */
|
||||
add_one_ip6_address (s_ip6, address, 64, gw);
|
||||
|
||||
/* DNS servers */
|
||||
inet_pton (AF_INET6, dns, &addr6);
|
||||
nm_setting_ip6_config_add_dns (s_ip6, &addr6);
|
||||
|
||||
/* DNS searches */
|
||||
nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com");
|
||||
|
||||
/* Write out the connection */
|
||||
owner_uid = geteuid ();
|
||||
owner_grp = getegid ();
|
||||
success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
|
||||
ASSERT (success == TRUE,
|
||||
"connection-write", "failed to allocate write keyfile: %s",
|
||||
error ? error->message : "(none)");
|
||||
|
||||
ASSERT (testfile != NULL,
|
||||
"connection-write", "didn't get keyfile name back after writing connection");
|
||||
|
||||
/* Read the connection back in and compare it to the one we just wrote out */
|
||||
reread = connection_from_file (testfile);
|
||||
ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
|
||||
|
||||
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
|
||||
"connection-write", "written and re-read connection weren't the same");
|
||||
|
||||
g_clear_error (&error);
|
||||
unlink (testfile);
|
||||
g_free (testfile);
|
||||
|
||||
g_object_unref (reread);
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
#define TEST_WIRED_MAC_CASE_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_MAC_Case"
|
||||
|
||||
static void
|
||||
|
|
@ -1042,6 +1308,9 @@ int main (int argc, char **argv)
|
|||
test_read_valid_wired_connection ();
|
||||
test_write_wired_connection ();
|
||||
|
||||
test_read_ip6_wired_connection ();
|
||||
test_write_ip6_wired_connection ();
|
||||
|
||||
test_read_wired_mac_case ();
|
||||
|
||||
test_read_valid_wireless_connection ();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue