device: merge branch 'th/device-mtu-rh1414901'

https://bugzilla.redhat.com/show_bug.cgi?id=1414901
This commit is contained in:
Thomas Haller
2017-10-24 16:07:49 +02:00
14 changed files with 338 additions and 172 deletions

View File

@@ -32,6 +32,7 @@
#include <libintl.h> #include <libintl.h>
#include <gmodule.h> #include <gmodule.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <net/if.h>
#if WITH_JANSSON #if WITH_JANSSON
#include <jansson.h> #include <jansson.h>
@@ -3675,36 +3676,41 @@ _nm_utils_generate_mac_address_mask_parse (const char *value,
gboolean gboolean
nm_utils_is_valid_iface_name (const char *name, GError **error) nm_utils_is_valid_iface_name (const char *name, GError **error)
{ {
g_return_val_if_fail (name != NULL, FALSE); int i;
if (*name == '\0') { g_return_val_if_fail (name, FALSE);
if (name[0] == '\0') {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is too short")); _("interface name is too short"));
return FALSE; return FALSE;
} }
if (strlen (name) >= 16) { if ( name[0] == '.'
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, && ( name[1] == '\0'
_("interface name is longer than 15 characters")); || ( name[1] == '.'
return FALSE; && name[2] == '\0'))) {
}
if (!strcmp (name, ".") || !strcmp (name, "..")) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is reserved")); _("interface name is reserved"));
return FALSE; return FALSE;
} }
while (*name) { for (i = 0; i < IFNAMSIZ; i++) {
if (*name == '/' || g_ascii_isspace (*name)) { char ch = name[i];
if (ch == '\0')
return TRUE;
if ( NM_IN_SET (ch, '/', ':')
|| g_ascii_isspace (ch)) {
g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name contains an invalid character")); _("interface name contains an invalid character"));
return FALSE; return FALSE;
} }
name++;
} }
return TRUE; g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
_("interface name is longer than 15 characters"));
return FALSE;
} }
/** /**

View File

@@ -118,6 +118,8 @@ gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self,
guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is_user_config); guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is_user_config);
void nm_device_commit_mtu (NMDevice *self);
/*****************************************************************************/ /*****************************************************************************/
#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \ #define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \

View File

@@ -51,6 +51,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceVlan,
typedef struct { typedef struct {
gulong parent_state_id; gulong parent_state_id;
gulong parent_hwaddr_id; gulong parent_hwaddr_id;
gulong parent_mtu_id;
guint vlan_id; guint vlan_id;
} NMDeviceVlanPrivate; } NMDeviceVlanPrivate;
@@ -85,6 +86,17 @@ parent_state_changed (NMDevice *parent,
nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason);
} }
static void
parent_mtu_maybe_changed (NMDevice *parent,
GParamSpec *pspec,
gpointer user_data)
{
/* the MTU of a VLAN device is limited by the parent's MTU.
*
* When the parent's MTU changes, try to re-set the MTU. */
nm_device_commit_mtu (user_data);
}
static void static void
parent_hwaddr_maybe_changed (NMDevice *parent, parent_hwaddr_maybe_changed (NMDevice *parent,
GParamSpec *pspec, GParamSpec *pspec,
@@ -143,6 +155,7 @@ parent_changed_notify (NMDevice *device,
* parent_changed_notify(). */ * parent_changed_notify(). */
nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); nm_clear_g_signal_handler (old_parent, &priv->parent_state_id);
nm_clear_g_signal_handler (old_parent, &priv->parent_hwaddr_id); nm_clear_g_signal_handler (old_parent, &priv->parent_hwaddr_id);
nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id);
if (new_parent) { if (new_parent) {
priv->parent_state_id = g_signal_connect (new_parent, priv->parent_state_id = g_signal_connect (new_parent,
@@ -154,6 +167,10 @@ parent_changed_notify (NMDevice *device,
G_CALLBACK (parent_hwaddr_maybe_changed), device); G_CALLBACK (parent_hwaddr_maybe_changed), device);
parent_hwaddr_maybe_changed (new_parent, NULL, self); parent_hwaddr_maybe_changed (new_parent, NULL, self);
priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU,
G_CALLBACK (parent_mtu_maybe_changed), device);
parent_mtu_maybe_changed (new_parent, NULL, self);
/* Set parent-dependent unmanaged flag */ /* Set parent-dependent unmanaged flag */
nm_device_set_unmanaged_by_flags (device, nm_device_set_unmanaged_by_flags (device,
NM_UNMANAGED_PARENT, NM_UNMANAGED_PARENT,
@@ -482,8 +499,10 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
/* Change MAC address to parent's one if needed */ /* Change MAC address to parent's one if needed */
parent_device = nm_device_parent_get_device (device); parent_device = nm_device_parent_get_device (device);
if (parent_device) if (parent_device) {
parent_hwaddr_maybe_changed (parent_device, NULL, device); parent_hwaddr_maybe_changed (parent_device, NULL, device);
parent_mtu_maybe_changed (parent_device, NULL, device);
}
s_vlan = (NMSettingVlan *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_VLAN); s_vlan = (NMSettingVlan *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_VLAN);
if (s_vlan) { if (s_vlan) {

View File

@@ -72,6 +72,7 @@
#include "nm-arping-manager.h" #include "nm-arping-manager.h"
#include "nm-connectivity.h" #include "nm-connectivity.h"
#include "nm-dbus-interface.h" #include "nm-dbus-interface.h"
#include "nm-device-vlan.h"
#include "nm-device-logging.h" #include "nm-device-logging.h"
_LOG_DECLARE_SELF (NMDevice); _LOG_DECLARE_SELF (NMDevice);
@@ -550,6 +551,7 @@ static void realize_start_setup (NMDevice *self,
const char *assume_state_connection_uuid, const char *assume_state_connection_uuid,
gboolean set_nm_owned, gboolean set_nm_owned,
NMUnmanFlagOp unmanaged_user_explicit); NMUnmanFlagOp unmanaged_user_explicit);
static void _set_mtu (NMDevice *self, guint32 mtu);
static void _commit_mtu (NMDevice *self, const NMIP4Config *config); static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
static void dhcp_schedule_restart (NMDevice *self, int addr_family, const char *reason); static void dhcp_schedule_restart (NMDevice *self, int addr_family, const char *reason);
static void _cancel_activation (NMDevice *self); static void _cancel_activation (NMDevice *self);
@@ -851,26 +853,29 @@ nm_device_ipv4_sysctl_set (NMDevice *self, const char *property, const char *val
NMPlatform *platform = nm_device_get_platform (self); NMPlatform *platform = nm_device_get_platform (self);
gs_free char *value_to_free = NULL; gs_free char *value_to_free = NULL;
const char *value_to_set; const char *value_to_set;
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
if (value) { if (value) {
value_to_set = value; value_to_set = value;
} else { } else {
/* Set to a default value when we've got a NULL @value. */ /* Set to a default value when we've got a NULL @value. */
value_to_free = nm_platform_sysctl_get (platform, value_to_free = nm_platform_sysctl_get (platform,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path ("default", property))); NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET, buf, "default", property)));
value_to_set = value_to_free; value_to_set = value_to_free;
} }
return nm_platform_sysctl_set (platform, return nm_platform_sysctl_set (platform,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (nm_device_get_ip_iface (self), property)), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET, buf, nm_device_get_ip_iface (self), property)),
value_to_set); value_to_set);
} }
static guint32 static guint32
nm_device_ipv4_sysctl_get_uint32 (NMDevice *self, const char *property, guint32 fallback) nm_device_ipv4_sysctl_get_uint32 (NMDevice *self, const char *property, guint32 fallback)
{ {
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_get_int_checked (nm_device_get_platform (self), return nm_platform_sysctl_get_int_checked (nm_device_get_platform (self),
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (nm_device_get_ip_iface (self), property)), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET, buf, nm_device_get_ip_iface (self), property)),
10, 10,
0, 0,
G_MAXUINT32, G_MAXUINT32,
@@ -880,14 +885,18 @@ nm_device_ipv4_sysctl_get_uint32 (NMDevice *self, const char *property, guint32
gboolean gboolean
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value) nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value)
{ {
return nm_platform_sysctl_set (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property)), value); char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_set (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, buf, nm_device_get_ip_iface (self), property)), value);
} }
static guint32 static guint32
nm_device_ipv6_sysctl_get_uint32 (NMDevice *self, const char *property, guint32 fallback) nm_device_ipv6_sysctl_get_uint32 (NMDevice *self, const char *property, guint32 fallback)
{ {
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return nm_platform_sysctl_get_int_checked (nm_device_get_platform (self), return nm_platform_sysctl_get_int_checked (nm_device_get_platform (self),
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property)), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, buf, nm_device_get_ip_iface (self), property)),
10, 10,
0, 0,
G_MAXUINT32, G_MAXUINT32,
@@ -2672,10 +2681,7 @@ device_link_changed (NMDevice *self)
_notify (self, PROP_DRIVER); _notify (self, PROP_DRIVER);
} }
if (priv->mtu != info.mtu) { _set_mtu (self, info.mtu);
priv->mtu = info.mtu;
_notify (self, PROP_MTU);
}
if (ifindex == nm_device_get_ip_ifindex (self)) if (ifindex == nm_device_get_ip_ifindex (self))
_stats_update_counters_from_pllink (self, &info); _stats_update_counters_from_pllink (self, &info);
@@ -3242,7 +3248,6 @@ realize_start_setup (NMDevice *self,
NMDeviceCapabilities capabilities = 0; NMDeviceCapabilities capabilities = 0;
NMConfig *config; NMConfig *config;
guint real_rate; guint real_rate;
guint32 mtu;
/* plink is a NMPlatformLink type, however, we require it to come from the platform /* plink is a NMPlatformLink type, however, we require it to come from the platform
* cache (where else would it come from?). */ * cache (where else would it come from?). */
@@ -3271,10 +3276,7 @@ realize_start_setup (NMDevice *self,
priv->mtu_initial = 0; priv->mtu_initial = 0;
priv->ip6_mtu_initial = 0; priv->ip6_mtu_initial = 0;
priv->ip6_mtu = 0; priv->ip6_mtu = 0;
if (priv->mtu) { _set_mtu (self, 0);
priv->mtu = 0;
_notify (self, PROP_MTU);
}
_assume_state_set (self, assume_state_guess_assume, assume_state_connection_uuid); _assume_state_set (self, assume_state_guess_assume, assume_state_connection_uuid);
@@ -3295,11 +3297,9 @@ realize_start_setup (NMDevice *self,
if (nm_platform_link_is_software (nm_device_get_platform (self), priv->ifindex)) if (nm_platform_link_is_software (nm_device_get_platform (self), priv->ifindex))
capabilities |= NM_DEVICE_CAP_IS_SOFTWARE; capabilities |= NM_DEVICE_CAP_IS_SOFTWARE;
mtu = nm_platform_link_get_mtu (nm_device_get_platform (self), priv->ifindex); _set_mtu (self,
if (priv->mtu != mtu) { nm_platform_link_get_mtu (nm_device_get_platform (self),
priv->mtu = mtu; priv->ifindex));
_notify (self, PROP_MTU);
}
nm_platform_link_get_driver_info (nm_device_get_platform (self), nm_platform_link_get_driver_info (nm_device_get_platform (self),
priv->ifindex, priv->ifindex,
@@ -3524,10 +3524,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
if (nm_clear_g_free (&priv->ip_iface)) if (nm_clear_g_free (&priv->ip_iface))
_notify (self, PROP_IP_IFACE); _notify (self, PROP_IP_IFACE);
if (priv->mtu != 0) { _set_mtu (self, 0);
priv->mtu = 0;
_notify (self, PROP_MTU);
}
if (priv->driver_version) { if (priv->driver_version) {
g_clear_pointer (&priv->driver_version, g_free); g_clear_pointer (&priv->driver_version, g_free);
@@ -7211,6 +7208,26 @@ nm_device_get_configured_mtu_for_wired (NMDevice *self, gboolean *out_is_user_co
/*****************************************************************************/ /*****************************************************************************/
static void
_set_mtu (NMDevice *self, guint32 mtu)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->mtu == mtu)
return;
priv->mtu = mtu;
_notify (self, PROP_MTU);
if (priv->master) {
/* changing the MTU of a slave, might require the master to reset
* it's MTU. Note that the master usually cannot set a MTU larger
* then the slave's. Hence, when the slave increases the MTU,
* master might want to retry setting the MTU. */
nm_device_commit_mtu (priv->master);
}
}
static void static void
_commit_mtu (NMDevice *self, const NMIP4Config *config) _commit_mtu (NMDevice *self, const NMIP4Config *config)
{ {
@@ -7230,8 +7247,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
return; return;
if (nm_device_sys_iface_state_is_external_or_assume (self)) { if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* for assumed connections we don't tamper with the MTU. This is /* for assumed connections we don't tamper with the MTU. */
* a bug and supposed to be fixed by the unmanaged/assumed rework. */
return; return;
} }
@@ -7331,6 +7347,7 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
}) })
if ( (mtu_desired && mtu_desired != mtu_plat) if ( (mtu_desired && mtu_desired != mtu_plat)
|| (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ())) { || (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ())) {
gboolean anticipated_failure = FALSE;
if (!priv->mtu_initial && !priv->ip6_mtu_initial) { if (!priv->mtu_initial && !priv->ip6_mtu_initial) {
/* before touching any of the MTU paramters, record the /* before touching any of the MTU paramters, record the
@@ -7340,19 +7357,52 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config)
} }
if (mtu_desired && mtu_desired != mtu_plat) { if (mtu_desired && mtu_desired != mtu_plat) {
nm_platform_link_set_mtu (nm_device_get_platform (self), ifindex, mtu_desired); if (nm_platform_link_set_mtu (nm_device_get_platform (self), ifindex, mtu_desired) == NM_PLATFORM_ERROR_CANT_SET_MTU) {
anticipated_failure = TRUE;
_LOGW (LOGD_DEVICE, "mtu: failure to set MTU. %s",
NM_IS_DEVICE_VLAN (self)
? "Is the parent's MTU size large enough?"
: (!c_list_is_empty (&priv->slaves)
? "Are the MTU sizes of the slaves large enough?"
: "Did you configure the MTU correctly?"));
}
priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_ms () + CARRIER_WAIT_TIME_AFTER_MTU_MS; priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_ms () + CARRIER_WAIT_TIME_AFTER_MTU_MS;
} }
if (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ()) { if (ip6_mtu && ip6_mtu != _IP6_MTU_SYS ()) {
nm_device_ipv6_sysctl_set (self, "mtu", if (!nm_device_ipv6_sysctl_set (self, "mtu",
nm_sprintf_buf (sbuf, "%u", (unsigned) ip6_mtu)); nm_sprintf_buf (sbuf, "%u", (unsigned) ip6_mtu))) {
int errsv = errno;
_NMLOG (anticipated_failure && errsv == EINVAL ? LOGL_DEBUG : LOGL_WARN,
LOGD_DEVICE,
"mtu: failure to set IPv6 MTU%s",
anticipated_failure && errsv == EINVAL
? ": Is the underlying MTU value successfully set?"
: "");
}
priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_ms () + CARRIER_WAIT_TIME_AFTER_MTU_MS; priv->carrier_wait_until_ms = nm_utils_get_monotonic_timestamp_ms () + CARRIER_WAIT_TIME_AFTER_MTU_MS;
} }
} }
#undef _IP6_MTU_SYS #undef _IP6_MTU_SYS
} }
void
nm_device_commit_mtu (NMDevice *self)
{
NMDeviceState state;
g_return_if_fail (NM_IS_DEVICE (self));
state = nm_device_get_state (self);
if ( state >= NM_DEVICE_STATE_CONFIG
&& state < NM_DEVICE_STATE_DEACTIVATING) {
_LOGT (LOGD_DEVICE, "mtu: commit-mtu...");
_commit_mtu (self, NM_DEVICE_GET_PRIVATE (self)->ip4_config);
} else
_LOGT (LOGD_DEVICE, "mtu: commit-mtu... skip due to state %s", nm_device_state_to_str (state));
}
static void static void
ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self) ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self)
{ {
@@ -7654,7 +7704,9 @@ save_ip6_properties (NMDevice *self)
g_hash_table_remove_all (priv->ip6_saved_properties); g_hash_table_remove_all (priv->ip6_saved_properties);
for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) { for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) {
value = nm_platform_sysctl_get (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i]))); char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
value = nm_platform_sysctl_get (nm_device_get_platform (self), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, buf, ifname, ip6_properties_to_save[i])));
if (value) { if (value) {
g_hash_table_insert (priv->ip6_saved_properties, g_hash_table_insert (priv->ip6_saved_properties,
(char *) ip6_properties_to_save[i], (char *) ip6_properties_to_save[i],
@@ -7714,9 +7766,11 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable)
} }
if (enable) { if (enable) {
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
/* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */
value = nm_platform_sysctl_get (nm_device_get_platform (self), value = nm_platform_sysctl_get (nm_device_get_platform (self),
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), "disable_ipv6"))); NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, buf, nm_device_get_ip_iface (self), "disable_ipv6")));
if (g_strcmp0 (value, "0") == 0) if (g_strcmp0 (value, "0") == 0)
nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
g_free (value); g_free (value);

View File

@@ -531,8 +531,10 @@ start (NMNDisc *ndisc)
static inline int static inline int
ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval) ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval)
{ {
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
return (int) nm_platform_sysctl_get_int_checked (platform, return (int) nm_platform_sysctl_get_int_checked (platform,
NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (ifname, property)), NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, buf, ifname, property)),
10, 10,
min, min,
max, max,

View File

@@ -2525,55 +2525,88 @@ nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timestamp_ns_
#define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/" #define IPV6_PROPERTY_DIR "/proc/sys/net/ipv6/conf/"
#define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/" #define IPV4_PROPERTY_DIR "/proc/sys/net/ipv4/conf/"
G_STATIC_ASSERT (sizeof (IPV4_PROPERTY_DIR) == sizeof (IPV6_PROPERTY_DIR)); G_STATIC_ASSERT (sizeof (IPV4_PROPERTY_DIR) == sizeof (IPV6_PROPERTY_DIR));
G_STATIC_ASSERT (NM_STRLEN (IPV6_PROPERTY_DIR) + IFNAMSIZ + 60 == NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE);
static const char * /**
_get_property_path (const char *ifname, * nm_utils_sysctl_ip_conf_path:
const char *property, * @addr_family: either AF_INET or AF_INET6.
gboolean ipv6) * @buf: the output buffer where to write the path. It
* must be at least NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE bytes
* long.
* @ifname: an interface name
* @property: a property name
*
* Returns: the path to IPv6 property @property on @ifname. Note that
* this returns the input argument @buf.
*/
const char *
nm_utils_sysctl_ip_conf_path (int addr_family, char *buf, const char *ifname, const char *property)
{ {
static char path[sizeof (IPV6_PROPERTY_DIR) + IFNAMSIZ + 32];
int len; int len;
ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname); nm_assert (buf);
nm_assert_addr_family (addr_family);
g_assert (nm_utils_is_valid_iface_name (ifname, NULL));
property = NM_ASSERT_VALID_PATH_COMPONENT (property); property = NM_ASSERT_VALID_PATH_COMPONENT (property);
len = g_snprintf (path, len = g_snprintf (buf,
sizeof (path), NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE,
"%s%s/%s", "%s%s/%s",
ipv6 ? IPV6_PROPERTY_DIR : IPV4_PROPERTY_DIR, addr_family == AF_INET6 ? IPV6_PROPERTY_DIR : IPV4_PROPERTY_DIR,
ifname, ifname,
property); property);
g_assert (len < sizeof (path) - 1); g_assert (len < NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE - 1);
return buf;
return path;
} }
/** gboolean
* nm_utils_ip6_property_path: nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char *ifname, const char *property)
* @ifname: an interface name
* @property: a property name
*
* Returns the path to IPv6 property @property on @ifname. Note that
* this uses a static buffer.
*/
const char *
nm_utils_ip6_property_path (const char *ifname, const char *property)
{ {
return _get_property_path (ifname, property, TRUE); g_return_val_if_fail (path, FALSE);
} NM_ASSERT_VALID_PATH_COMPONENT (property);
g_assert (!ifname || nm_utils_is_valid_iface_name (ifname, NULL));
/** if (addr_family == AF_INET) {
* nm_utils_ip4_property_path: if (!g_str_has_prefix (path, IPV4_PROPERTY_DIR))
* @ifname: an interface name return FALSE;
* @property: a property name path += NM_STRLEN (IPV4_PROPERTY_DIR);
* } else if (addr_family == AF_INET6) {
* Returns the path to IPv4 property @property on @ifname. Note that if (!g_str_has_prefix (path, IPV6_PROPERTY_DIR))
* this uses a static buffer. return FALSE;
*/ path += NM_STRLEN (IPV6_PROPERTY_DIR);
const char * } else
nm_utils_ip4_property_path (const char *ifname, const char *property) g_return_val_if_reached (FALSE);
{
return _get_property_path (ifname, property, FALSE); if (ifname) {
if (!g_str_has_prefix (path, ifname))
return FALSE;
path += strlen (ifname);
if (path[0] != '/')
return FALSE;
path++;
} else {
const char *slash;
char buf[IFNAMSIZ];
gsize l;
slash = strchr (path, '/');
if (!slash)
return FALSE;
l = slash - path;
if (l >= IFNAMSIZ)
return FALSE;
memcpy (buf, path, l);
buf[l] = '\0';
if (!nm_utils_is_valid_iface_name (buf, NULL))
return FALSE;
path = slash + 1;
}
if (!nm_streq (path, property))
return FALSE;
return TRUE;
} }
gboolean gboolean

View File

@@ -248,8 +248,12 @@ gint64 nm_utils_monotonic_timestamp_as_boottime (gint64 timestamp, gint64 timest
gboolean nm_utils_is_valid_path_component (const char *name); gboolean nm_utils_is_valid_path_component (const char *name);
const char *NM_ASSERT_VALID_PATH_COMPONENT (const char *name); const char *NM_ASSERT_VALID_PATH_COMPONENT (const char *name);
const char *nm_utils_ip6_property_path (const char *ifname, const char *property);
const char *nm_utils_ip4_property_path (const char *ifname, const char *property); #define NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE 100
const char *nm_utils_sysctl_ip_conf_path (int addr_family, char *buf, const char *ifname, const char *property);
gboolean nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, const char *ifname, const char *property);
gboolean nm_utils_is_specific_hostname (const char *name); gboolean nm_utils_is_specific_hostname (const char *name);

View File

@@ -222,9 +222,10 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
if (changed & NM_NDISC_CONFIG_MTU) { if (changed & NM_NDISC_CONFIG_MTU) {
char val[16]; char val[16];
char sysctl_path_buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
g_snprintf (val, sizeof (val), "%d", rdata->mtu); g_snprintf (val, sizeof (val), "%d", rdata->mtu);
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "mtu")), val); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, sysctl_path_buf, global_opt.ifname, "mtu")), val);
} }
nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0); nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
@@ -344,6 +345,7 @@ main (int argc, char *argv[])
gconstpointer tmp; gconstpointer tmp;
gs_free NMUtilsIPv6IfaceId *iid = NULL; gs_free NMUtilsIPv6IfaceId *iid = NULL;
guint sd_id; guint sd_id;
char sysctl_path_buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
nm_g_type_init (); nm_g_type_init ();
@@ -448,7 +450,7 @@ main (int argc, char *argv[])
} }
if (global_opt.dhcp4_address) { if (global_opt.dhcp4_address) {
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries")), "1"); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET, sysctl_path_buf, global_opt.ifname, "promote_secondaries")), "1");
dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
nm_platform_get_multi_idx (NM_PLATFORM_GET), nm_platform_get_multi_idx (NM_PLATFORM_GET),
@@ -497,10 +499,10 @@ main (int argc, char *argv[])
if (iid) if (iid)
nm_ndisc_set_iid (ndisc, *iid); nm_ndisc_set_iid (ndisc, *iid);
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra")), "1"); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, sysctl_path_buf, global_opt.ifname, "accept_ra")), "1");
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr")), "0"); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, sysctl_path_buf, global_opt.ifname, "accept_ra_defrtr")), "0");
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo")), "0"); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, sysctl_path_buf, global_opt.ifname, "accept_ra_pinfo")), "0");
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref")), "0"); nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (AF_INET6, sysctl_path_buf, global_opt.ifname, "accept_ra_rtr_pref")), "0");
g_signal_connect (NM_PLATFORM_GET, g_signal_connect (NM_PLATFORM_GET,
NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,

View File

@@ -585,7 +585,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t
return NM_PLATFORM_ERROR_SUCCESS; return NM_PLATFORM_ERROR_SUCCESS;
} }
static gboolean static NMPlatformError
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
{ {
NMFakePlatformLink *device = link_get (platform, ifindex); NMFakePlatformLink *device = link_get (platform, ifindex);
@@ -593,13 +593,13 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
if (!device) { if (!device) {
_LOGE ("failure changing link: netlink error (No such device)"); _LOGE ("failure changing link: netlink error (No such device)");
return FALSE; return NM_PLATFORM_ERROR_EXISTS;
} }
obj_tmp = nmp_object_clone (device->obj, FALSE); obj_tmp = nmp_object_clone (device->obj, FALSE);
obj_tmp->link.mtu = mtu; obj_tmp->link.mtu = mtu;
link_set_obj (platform, device, obj_tmp); link_set_obj (platform, device, obj_tmp);
return TRUE; return NM_PLATFORM_ERROR_SUCCESS;
} }
static gboolean static gboolean

View File

@@ -206,6 +206,21 @@ typedef enum {
INFINIBAND_ACTION_DELETE_CHILD, INFINIBAND_ACTION_DELETE_CHILD,
} InfinibandAction; } InfinibandAction;
typedef enum {
CHANGE_LINK_TYPE_UNSPEC,
CHANGE_LINK_TYPE_SET_MTU,
CHANGE_LINK_TYPE_SET_ADDRESS,
} ChangeLinkType;
typedef struct {
union {
struct {
gconstpointer address;
gsize length;
} set_address;
};
} ChangeLinkData;
enum { enum {
DELAYED_ACTION_IDX_REFRESH_ALL_LINKS, DELAYED_ACTION_IDX_REFRESH_ALL_LINKS,
DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES, DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES,
@@ -2934,7 +2949,7 @@ sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_pop_netns NMPNetns *netns = NULL;
int fd, tries; int fd, tries;
gssize nwrote; gssize nwrote;
gsize len; gssize len;
char *actual; char *actual;
gs_free char *actual_free = NULL; gs_free char *actual_free = NULL;
int errsv; int errsv;
@@ -2989,6 +3004,7 @@ sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
* about to write. * about to write.
*/ */
len = strlen (value) + 1; len = strlen (value) + 1;
nm_assert (len > 0);
if (len > 512) if (len > 512)
actual = actual_free = g_malloc (len + 1); actual = actual_free = g_malloc (len + 1);
else else
@@ -3010,8 +3026,19 @@ sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *pat
break; break;
} }
} }
if (nwrote == -1 && errsv != EEXIST) { if (nwrote == -1) {
_LOGE ("sysctl: failed to set '%s' to '%s': (%d) %s", NMLogLevel level = LOGL_ERR;
if (errsv == EEXIST) {
level = LOGL_DEBUG;
} else if ( errsv == EINVAL
&& nm_utils_sysctl_ip_conf_is_path (AF_INET6, path, NULL, "mtu")) {
/* setting the MTU can fail under regular conditions. Suppress
* logging a warning. */
level = LOGL_DEBUG;
}
_NMLOG (level, "sysctl: failed to set '%s' to '%s': (%d) %s",
path, value, errsv, strerror (errsv)); path, value, errsv, strerror (errsv));
} else if (nwrote < len - 1) { } else if (nwrote < len - 1) {
_LOGE ("sysctl: failed to set '%s' to '%s' after three attempts", _LOGE ("sysctl: failed to set '%s' to '%s' after three attempts",
@@ -4410,25 +4437,38 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *
return success; return success;
} }
static WaitForNlResponseResult static NMPlatformError
do_change_link_request (NMPlatform *platform, do_change_link (NMPlatform *platform,
ChangeLinkType change_link_type,
int ifindex, int ifindex,
struct nl_msg *nlmsg) struct nl_msg *nlmsg,
const ChangeLinkData *data)
{ {
nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_pop_netns NMPNetns *netns = NULL;
WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
int nle; int nle;
WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN;
char s_buf[256];
NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
NMLogLevel log_level = LOGL_DEBUG;
const char *log_result = "failure";
const char *log_detail = "";
gs_free char *log_detail_free = NULL;
const NMPObject *obj_cache;
if (!nm_platform_netns_push (platform, &netns)) if (!nm_platform_netns_push (platform, &netns)) {
return WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; log_level = LOGL_ERR;
log_detail = ", failure to change network namespace";
goto out;
}
retry: retry:
nle = _nl_send_nlmsg (platform, nlmsg, &seq_result, DELAYED_ACTION_RESPONSE_TYPE_VOID, NULL); nle = _nl_send_nlmsg (platform, nlmsg, &seq_result, DELAYED_ACTION_RESPONSE_TYPE_VOID, NULL);
if (nle < 0) { if (nle < 0) {
_LOGE ("do-change-link[%d]: failure sending netlink request \"%s\" (%d)", log_level = LOGL_ERR;
ifindex, log_detail_free = g_strdup_printf (", failure sending netlink request: %s (%d)",
nl_geterror (nle), -nle); nl_geterror (nle), -nle);
return WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; log_detail = log_detail_free;
goto out;
} }
/* always refetch the link after changing it. There seems to be issues /* always refetch the link after changing it. There seems to be issues
@@ -4444,18 +4484,6 @@ retry:
nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK; nlmsg_hdr (nlmsg)->nlmsg_type = RTM_SETLINK;
goto retry; goto retry;
} }
return seq_result;
}
static NMPlatformError
do_change_link_result (NMPlatform *platform,
int ifindex,
WaitForNlResponseResult seq_result)
{
char s_buf[256];
NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS;
NMLogLevel log_level = LOGL_DEBUG;
const char *log_result = "failure", *log_detail = "";
if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) { if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) {
log_result = "success"; log_result = "success";
@@ -4464,6 +4492,20 @@ do_change_link_result (NMPlatform *platform,
} else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) { } else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) {
log_detail = ", firmware not found"; log_detail = ", firmware not found";
result = NM_PLATFORM_ERROR_NO_FIRMWARE; result = NM_PLATFORM_ERROR_NO_FIRMWARE;
} else if ( NM_IN_SET (-((int) seq_result), ERANGE)
&& change_link_type == CHANGE_LINK_TYPE_SET_MTU) {
log_detail = ", setting MTU to requested size is not possible";
result = NM_PLATFORM_ERROR_CANT_SET_MTU;
} else if ( NM_IN_SET (-((int) seq_result), ENFILE)
&& change_link_type == CHANGE_LINK_TYPE_SET_ADDRESS
&& (obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex))
&& obj_cache->link.addr.len == data->set_address.length
&& memcmp (obj_cache->link.addr.data, data->set_address.address, data->set_address.length) == 0) {
/* workaround ENFILE which may be wrongly returned (bgo #770456).
* If the MAC address is as expected, assume success? */
log_result = "success";
log_detail = " (assume success changing address)";
result = NM_PLATFORM_ERROR_SUCCESS;
} else if (NM_IN_SET (-((int) seq_result), ENODEV)) { } else if (NM_IN_SET (-((int) seq_result), ENODEV)) {
log_level = LOGL_DEBUG; log_level = LOGL_DEBUG;
result = NM_PLATFORM_ERROR_NOT_FOUND; result = NM_PLATFORM_ERROR_NOT_FOUND;
@@ -4471,27 +4513,17 @@ do_change_link_result (NMPlatform *platform,
log_level = LOGL_WARN; log_level = LOGL_WARN;
result = NM_PLATFORM_ERROR_UNSPECIFIED; result = NM_PLATFORM_ERROR_UNSPECIFIED;
} }
out:
_NMLOG (log_level, _NMLOG (log_level,
"do-change-link[%d]: %s changing link: %s%s", "do-change-link[%d]: %s changing link: %s%s",
ifindex, ifindex,
log_result, log_result,
wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)), wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)),
log_detail); log_detail);
return result; return result;
} }
static NMPlatformError
do_change_link (NMPlatform *platform,
int ifindex,
struct nl_msg *nlmsg)
{
WaitForNlResponseResult seq_result;
seq_result = do_change_link_request (platform, ifindex, nlmsg);
return do_change_link_result (platform, ifindex, seq_result);
}
static gboolean static gboolean
link_add (NMPlatform *platform, link_add (NMPlatform *platform,
const char *name, const char *name,
@@ -4583,7 +4615,7 @@ link_set_netns (NMPlatform *platform,
return FALSE; return FALSE;
NLA_PUT (nlmsg, IFLA_NET_NS_FD, 4, &netns_fd); NLA_PUT (nlmsg, IFLA_NET_NS_FD, 4, &netns_fd);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS;
nla_put_failure: nla_put_failure:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
@@ -4613,7 +4645,7 @@ link_change_flags (NMPlatform *platform,
flags_set); flags_set);
if (!nlmsg) if (!nlmsg)
return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_UNSPECIFIED;
return do_change_link (platform, ifindex, nlmsg); return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL);
} }
static gboolean static gboolean
@@ -4682,7 +4714,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable
|| !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL))
g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); g_return_val_if_reached (NM_PLATFORM_ERROR_BUG);
return do_change_link (platform, ifindex, nlmsg); return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL);
} }
static gboolean static gboolean
@@ -4697,7 +4729,7 @@ link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid)
if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid)) if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid))
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS;
} }
static gboolean static gboolean
@@ -4762,8 +4794,12 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
{ {
nm_auto_nlmsg struct nl_msg *nlmsg = NULL; nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
gs_free char *mac = NULL; gs_free char *mac = NULL;
WaitForNlResponseResult seq_result; const ChangeLinkData d = {
char s_buf[256]; .set_address = {
.address = address,
.length = length,
},
};
if (!address || !length) if (!address || !length)
g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); g_return_val_if_reached (NM_PLATFORM_ERROR_BUG);
@@ -4783,30 +4819,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size
NLA_PUT (nlmsg, IFLA_ADDRESS, length, address); NLA_PUT (nlmsg, IFLA_ADDRESS, length, address);
seq_result = do_change_link_request (platform, ifindex, nlmsg); return do_change_link (platform, CHANGE_LINK_TYPE_SET_ADDRESS, ifindex, nlmsg, &d);
if (NM_IN_SET (-((int) seq_result), ENFILE)) {
const NMPObject *obj_cache;
/* workaround ENFILE which may be wrongly returned (bgo #770456).
* If the MAC address is as expected, assume success? */
obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex);
if ( obj_cache
&& obj_cache->link.addr.len == length
&& memcmp (obj_cache->link.addr.data, address, length) == 0) {
_NMLOG (LOGL_DEBUG,
"do-change-link[%d]: %s changing link: %s%s",
ifindex,
"success",
wait_for_nl_response_to_string (seq_result, s_buf, sizeof (s_buf)),
" (assume success changing address)");
return NM_PLATFORM_ERROR_SUCCESS;
}
}
return do_change_link_result (platform, ifindex, seq_result);
nla_put_failure: nla_put_failure:
g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED);
} }
@@ -4829,7 +4842,7 @@ link_set_name (NMPlatform *platform, int ifindex, const char *name)
NLA_PUT (nlmsg, IFLA_IFNAME, strlen (name) + 1, name); NLA_PUT (nlmsg, IFLA_IFNAME, strlen (name) + 1, name);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS;
nla_put_failure: nla_put_failure:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
} }
@@ -4848,7 +4861,7 @@ link_get_permanent_address (NMPlatform *platform,
return nmp_utils_ethtool_get_permanent_address (ifindex, buf, length); return nmp_utils_ethtool_get_permanent_address (ifindex, buf, length);
} }
static gboolean static NMPlatformError
link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
{ {
nm_auto_nlmsg struct nl_msg *nlmsg = NULL; nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
@@ -4866,7 +4879,7 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu)
NLA_PUT_U32 (nlmsg, IFLA_MTU, mtu); NLA_PUT_U32 (nlmsg, IFLA_MTU, mtu);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_SET_MTU, ifindex, nlmsg, NULL);
nla_put_failure: nla_put_failure:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
} }
@@ -5574,7 +5587,7 @@ link_vlan_change (NMPlatform *platform,
new_n_egress_map)) new_n_egress_map))
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS;
} }
static int static int
@@ -5654,7 +5667,7 @@ link_enslave (NMPlatform *platform, int master, int slave)
NLA_PUT_U32 (nlmsg, IFLA_MASTER, master); NLA_PUT_U32 (nlmsg, IFLA_MASTER, master);
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS;
nla_put_failure: nla_put_failure:
g_return_val_if_reached (FALSE); g_return_val_if_reached (FALSE);
} }

View File

@@ -240,6 +240,7 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_nm_platform_error_to_string, NMPlatformError
NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NO_FIRMWARE, "no-firmware"), NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NO_FIRMWARE, "no-firmware"),
NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_OPNOTSUPP, "not-supported"), NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_OPNOTSUPP, "not-supported"),
NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NETLINK, "netlink"), NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NETLINK, "netlink"),
NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_CANT_SET_MTU, "cant-set-mtu"),
NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT), NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT),
); );
@@ -413,6 +414,7 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface,
{ {
const char *path; const char *path;
gint64 cur; gint64 cur;
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
_CHECK_SELF (self, klass, FALSE); _CHECK_SELF (self, klass, FALSE);
@@ -424,7 +426,7 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface,
if (value < 10) if (value < 10)
return FALSE; return FALSE;
path = nm_utils_ip6_property_path (iface, "hop_limit"); path = nm_utils_sysctl_ip_conf_path (AF_INET6, buf, iface, "hop_limit");
cur = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 1, G_MAXINT32, -1); cur = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 1, G_MAXINT32, -1);
/* only allow increasing the hop-limit to avoid DOS by an attacker /* only allow increasing the hop-limit to avoid DOS by an attacker
@@ -1498,7 +1500,7 @@ nm_platform_link_set_noarp (NMPlatform *self, int ifindex)
* *
* Set interface MTU. * Set interface MTU.
*/ */
gboolean NMPlatformError
nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu) nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu)
{ {
_CHECK_SELF (self, klass, FALSE); _CHECK_SELF (self, klass, FALSE);

View File

@@ -166,6 +166,7 @@ typedef enum { /*< skip >*/
NM_PLATFORM_ERROR_NO_FIRMWARE, NM_PLATFORM_ERROR_NO_FIRMWARE,
NM_PLATFORM_ERROR_OPNOTSUPP, NM_PLATFORM_ERROR_OPNOTSUPP,
NM_PLATFORM_ERROR_NETLINK, NM_PLATFORM_ERROR_NETLINK,
NM_PLATFORM_ERROR_CANT_SET_MTU,
} NMPlatformError; } NMPlatformError;
#define NM_PLATFORM_LINK_OTHER_NETNS (-1) #define NM_PLATFORM_LINK_OTHER_NETNS (-1)
@@ -718,7 +719,7 @@ typedef struct {
guint8 *buf, guint8 *buf,
size_t *length); size_t *length);
NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length);
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); NMPlatformError (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name); gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name);
gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs); gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs);
@@ -1060,7 +1061,7 @@ gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtils
gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length); gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length);
NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);
gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); NMPlatformError nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu);
gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name); gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name);
gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs); gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs);

View File

@@ -76,7 +76,7 @@ test_bogus(void)
g_assert (!addrlen); g_assert (!addrlen);
g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL));
g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU)); g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU) != NM_PLATFORM_ERROR_SUCCESS);
g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX)); g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX));
@@ -603,7 +603,7 @@ test_internal (void)
accept_signal (link_changed); accept_signal (link_changed);
/* Set MTU */ /* Set MTU */
g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU)); g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU) == NM_PLATFORM_ERROR_SUCCESS);
g_assert_cmpint (nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex), ==, MTU); g_assert_cmpint (nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex), ==, MTU);
accept_signal (link_changed); accept_signal (link_changed);

View File

@@ -272,6 +272,32 @@ test_nm_utils_log_connection_diff (void)
/*****************************************************************************/ /*****************************************************************************/
static void
do_test_sysctl_ip_conf (int addr_family,
const char *iface,
const char *property)
{
char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
const char *pp;
pp = nm_utils_sysctl_ip_conf_path (addr_family, path, iface, property);
g_assert (pp == path);
g_assert (path[0] == '/');
g_assert (nm_utils_sysctl_ip_conf_is_path (addr_family, path, iface, property));
g_assert (nm_utils_sysctl_ip_conf_is_path (addr_family, path, NULL, property));
}
static void
test_nm_utils_sysctl_ip_conf_path (void)
{
do_test_sysctl_ip_conf (AF_INET6, "a", "mtu");
do_test_sysctl_ip_conf (AF_INET6, "eth0", "mtu");
do_test_sysctl_ip_conf (AF_INET6, "e23456789012345", "mtu");
}
/*****************************************************************************/
static NMConnection * static NMConnection *
_match_connection_new (void) _match_connection_new (void)
{ {
@@ -1716,6 +1742,8 @@ main (int argc, char **argv)
g_test_add_func ("/general/nm_utils_ip6_address_same_prefix", test_nm_utils_ip6_address_same_prefix); g_test_add_func ("/general/nm_utils_ip6_address_same_prefix", test_nm_utils_ip6_address_same_prefix);
g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff); g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff);
g_test_add_func ("/general/nm_utils_sysctl_ip_conf_path", test_nm_utils_sysctl_ip_conf_path);
g_test_add_func ("/general/exp10", test_nm_utils_exp10); g_test_add_func ("/general/exp10", test_nm_utils_exp10);
g_test_add_func ("/general/connection-match/basic", test_connection_match_basic); g_test_add_func ("/general/connection-match/basic", test_connection_match_basic);